mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
Merge branch 'jdk:master' into JDK-8351623-sve
This commit is contained in:
commit
71a1fa41fd
12
.github/workflows/main.yml
vendored
12
.github/workflows/main.yml
vendored
@ -327,8 +327,8 @@ jobs:
|
||||
uses: ./.github/workflows/build-macos.yml
|
||||
with:
|
||||
platform: macos-x64
|
||||
runs-on: 'macos-13'
|
||||
xcode-toolset-version: '14.3.1'
|
||||
runs-on: 'macos-15-intel'
|
||||
xcode-toolset-version: '16.4'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
dry-run: ${{ needs.prepare.outputs.dry-run == 'true' }}
|
||||
@ -340,8 +340,8 @@ jobs:
|
||||
uses: ./.github/workflows/build-macos.yml
|
||||
with:
|
||||
platform: macos-aarch64
|
||||
runs-on: 'macos-14'
|
||||
xcode-toolset-version: '15.4'
|
||||
runs-on: 'macos-15'
|
||||
xcode-toolset-version: '16.4'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
dry-run: ${{ needs.prepare.outputs.dry-run == 'true' }}
|
||||
@ -432,9 +432,9 @@ jobs:
|
||||
with:
|
||||
platform: macos-aarch64
|
||||
bootjdk-platform: macos-aarch64
|
||||
runs-on: macos-14
|
||||
runs-on: macos-15
|
||||
dry-run: ${{ needs.prepare.outputs.dry-run == 'true' }}
|
||||
xcode-toolset-version: '15.4'
|
||||
xcode-toolset-version: '16.4'
|
||||
debug-suffix: -debug
|
||||
|
||||
test-windows-x64:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -25,3 +25,4 @@ NashornProfile.txt
|
||||
**/core.[0-9]*
|
||||
*.rej
|
||||
*.orig
|
||||
test/benchmarks/**/target
|
||||
|
||||
@ -1859,8 +1859,6 @@ difference.</p>
|
||||
<h3 id="additional-undecided-features">Additional Undecided
|
||||
Features</h3>
|
||||
<ul>
|
||||
<li><p>Trailing return type syntax for functions (<a
|
||||
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm">n2541</a>)</p></li>
|
||||
<li><p>Member initializers and aggregates (<a
|
||||
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3653.html">n3653</a>)</p></li>
|
||||
<li><p>Rvalue references and move semantics</p></li>
|
||||
|
||||
@ -1853,9 +1853,6 @@ See Object Lifetime: C++17 6.8/8, C++20 6.7.3/8
|
||||
|
||||
### Additional Undecided Features
|
||||
|
||||
* Trailing return type syntax for functions
|
||||
([n2541](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm))
|
||||
|
||||
* Member initializers and aggregates
|
||||
([n3653](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3653.html))
|
||||
|
||||
|
||||
@ -450,7 +450,7 @@ itself (<code>-timeoutFactor</code>). Also, some test cases that
|
||||
programmatically wait a certain amount of time will apply this factor.
|
||||
If we run in forced compilation mode (<code>-Xcomp</code>), the build
|
||||
system will automatically adjust this factor to compensate for less
|
||||
performance. Defaults to 1.</p>
|
||||
performance. Defaults to 4.</p>
|
||||
<h4 id="failure_handler_timeout">FAILURE_HANDLER_TIMEOUT</h4>
|
||||
<p>Sets the argument <code>-timeoutHandlerTimeout</code> for JTReg. The
|
||||
default value is 0. This is only valid if the failure handler is
|
||||
|
||||
@ -387,7 +387,7 @@ The `TIMEOUT_FACTOR` is forwarded to JTReg framework itself
|
||||
(`-timeoutFactor`). Also, some test cases that programmatically wait a
|
||||
certain amount of time will apply this factor. If we run in forced
|
||||
compilation mode (`-Xcomp`), the build system will automatically
|
||||
adjust this factor to compensate for less performance. Defaults to 1.
|
||||
adjust this factor to compensate for less performance. Defaults to 4.
|
||||
|
||||
#### FAILURE_HANDLER_TIMEOUT
|
||||
|
||||
|
||||
@ -114,7 +114,6 @@ ifeq ($(HSDIS_BACKEND), binutils)
|
||||
TOOLCHAIN_TYPE := gcc
|
||||
OPENJDK_TARGET_OS := linux
|
||||
OPENJDK_TARGET_OS_TYPE := unix
|
||||
CC_OUT_OPTION := -o$(SPACE)
|
||||
GENDEPS_FLAGS := -MMD -MF
|
||||
CFLAGS_DEBUG_SYMBOLS := -g
|
||||
DISABLED_WARNINGS :=
|
||||
|
||||
@ -946,8 +946,8 @@ define SetupRunJtregTestBody
|
||||
JTREG_ALL_OPTIONS := $$(JTREG_JAVA_OPTIONS) $$(JTREG_VM_OPTIONS)
|
||||
|
||||
JTREG_AUTO_PROBLEM_LISTS :=
|
||||
# Please reach consensus before changing this. It was not easy changing it to a `1`.
|
||||
JTREG_AUTO_TIMEOUT_FACTOR := 1
|
||||
# Please reach consensus before changing this.
|
||||
JTREG_AUTO_TIMEOUT_FACTOR := 4
|
||||
|
||||
ifneq ($$(findstring -Xcomp, $$(JTREG_ALL_OPTIONS)), )
|
||||
JTREG_AUTO_PROBLEM_LISTS += ProblemList-Xcomp.txt
|
||||
|
||||
@ -116,6 +116,9 @@ else ifeq ($(call isTargetOs, aix), true)
|
||||
$(eval STATIC_LIB_EXPORT_FILES += $(lib).exp) \
|
||||
)
|
||||
STATIC_LIBS := -Wl,-bexpfull $(STATIC_LIB_FILES) $(addprefix -Wl$(COMMA)-bE:, $(STATIC_LIB_EXPORT_FILES))
|
||||
ifeq ($(DEBUG_LEVEL), slowdebug)
|
||||
STATIC_LIBS += -Wl,-bbigtoc
|
||||
endif
|
||||
else
|
||||
$(error Unsupported platform)
|
||||
endif
|
||||
|
||||
@ -363,7 +363,7 @@ AC_DEFUN_ONCE([BASIC_SETUP_COMPLEX_TOOLS],
|
||||
|
||||
# Check if it's a GNU date compatible version
|
||||
AC_MSG_CHECKING([if date is a GNU compatible version])
|
||||
check_date=`$DATE --version 2>&1 | $GREP "GNU\|BusyBox"`
|
||||
check_date=`$DATE --version 2>&1 | $GREP "GNU\|BusyBox\|uutils"`
|
||||
if test "x$check_date" != x; then
|
||||
AC_MSG_RESULT([yes])
|
||||
IS_GNU_DATE=yes
|
||||
|
||||
@ -408,27 +408,6 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
|
||||
AC_MSG_CHECKING([if Boot JDK is 32 or 64 bits])
|
||||
AC_MSG_RESULT([$BOOT_JDK_BITS])
|
||||
|
||||
# Try to enable CDS
|
||||
AC_MSG_CHECKING([for local Boot JDK Class Data Sharing (CDS)])
|
||||
BOOT_JDK_CDS_ARCHIVE=$CONFIGURESUPPORT_OUTPUTDIR/classes.jsa
|
||||
UTIL_ADD_JVM_ARG_IF_OK([-XX:+UnlockDiagnosticVMOptions -XX:-VerifySharedSpaces -XX:SharedArchiveFile=$BOOT_JDK_CDS_ARCHIVE],boot_jdk_cds_args,[$JAVA])
|
||||
|
||||
if test "x$boot_jdk_cds_args" != x; then
|
||||
# Try creating a CDS archive
|
||||
$JAVA $boot_jdk_cds_args -Xshare:dump > /dev/null 2>&1
|
||||
if test $? -eq 0; then
|
||||
BOOTJDK_USE_LOCAL_CDS=true
|
||||
AC_MSG_RESULT([yes, created])
|
||||
else
|
||||
# Generation failed, don't use CDS.
|
||||
BOOTJDK_USE_LOCAL_CDS=false
|
||||
AC_MSG_RESULT([no, creation failed])
|
||||
fi
|
||||
else
|
||||
BOOTJDK_USE_LOCAL_CDS=false
|
||||
AC_MSG_RESULT([no, -XX:SharedArchiveFile not supported])
|
||||
fi
|
||||
|
||||
BOOTJDK_SETUP_CLASSPATH
|
||||
])
|
||||
|
||||
@ -444,13 +423,8 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
|
||||
# Force en-US environment
|
||||
UTIL_ADD_JVM_ARG_IF_OK([-Duser.language=en -Duser.country=US],boot_jdk_jvmargs,[$JAVA])
|
||||
|
||||
if test "x$BOOTJDK_USE_LOCAL_CDS" = xtrue; then
|
||||
# Use our own CDS archive
|
||||
UTIL_ADD_JVM_ARG_IF_OK([$boot_jdk_cds_args -Xshare:auto],boot_jdk_jvmargs,[$JAVA])
|
||||
else
|
||||
# Otherwise optimistically use the system-wide one, if one is present
|
||||
UTIL_ADD_JVM_ARG_IF_OK([-Xshare:auto],boot_jdk_jvmargs,[$JAVA])
|
||||
fi
|
||||
UTIL_ADD_JVM_ARG_IF_OK([-Xlog:all=off:stdout],boot_jdk_jvmargs,[$JAVA])
|
||||
UTIL_ADD_JVM_ARG_IF_OK([-Xlog:all=warning:stderr],boot_jdk_jvmargs,[$JAVA])
|
||||
|
||||
# Finally append user provided options to allow them to override.
|
||||
UTIL_ADD_JVM_ARG_IF_OK([$USER_BOOT_JDK_OPTIONS],boot_jdk_jvmargs,[$JAVA])
|
||||
@ -597,10 +571,9 @@ AC_DEFUN([BOOTJDK_SETUP_BUILD_JDK],
|
||||
AC_ARG_WITH(build-jdk, [AS_HELP_STRING([--with-build-jdk],
|
||||
[path to JDK of same version as is being built@<:@the newly built JDK@:>@])])
|
||||
|
||||
CREATE_BUILDJDK=false
|
||||
EXTERNAL_BUILDJDK=false
|
||||
BUILD_JDK_FOUND="no"
|
||||
EXTERNAL_BUILDJDK_PATH=""
|
||||
if test "x$with_build_jdk" != "x"; then
|
||||
BUILD_JDK_FOUND=no
|
||||
BOOTJDK_CHECK_BUILD_JDK([
|
||||
if test "x$with_build_jdk" != x; then
|
||||
BUILD_JDK=$with_build_jdk
|
||||
@ -608,40 +581,15 @@ AC_DEFUN([BOOTJDK_SETUP_BUILD_JDK],
|
||||
AC_MSG_NOTICE([Found potential Build JDK using configure arguments])
|
||||
fi
|
||||
])
|
||||
EXTERNAL_BUILDJDK=true
|
||||
else
|
||||
if test "x$COMPILE_TYPE" = "xcross"; then
|
||||
BUILD_JDK="\$(BUILDJDK_OUTPUTDIR)/jdk"
|
||||
BUILD_JDK_FOUND=yes
|
||||
CREATE_BUILDJDK=true
|
||||
if test "x$BUILD_JDK_FOUND" != "xyes"; then
|
||||
AC_MSG_CHECKING([for Build JDK])
|
||||
AC_MSG_RESULT([yes, will build it for the host platform])
|
||||
else
|
||||
BUILD_JDK="\$(JDK_OUTPUTDIR)"
|
||||
BUILD_JDK_FOUND=yes
|
||||
AC_MSG_CHECKING([for Build JDK])
|
||||
AC_MSG_RESULT([yes, will use output dir])
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Could not find a suitable Build JDK])
|
||||
fi
|
||||
EXTERNAL_BUILDJDK_PATH="$BUILD_JDK"
|
||||
fi
|
||||
|
||||
# Since these tools do not yet exist, we cannot use UTIL_FIXUP_EXECUTABLE to
|
||||
# detect the need of fixpath
|
||||
JMOD="$BUILD_JDK/bin/jmod"
|
||||
UTIL_ADD_FIXPATH(JMOD)
|
||||
JLINK="$BUILD_JDK/bin/jlink"
|
||||
UTIL_ADD_FIXPATH(JLINK)
|
||||
AC_SUBST(JMOD)
|
||||
AC_SUBST(JLINK)
|
||||
|
||||
if test "x$BUILD_JDK_FOUND" != "xyes"; then
|
||||
AC_MSG_CHECKING([for Build JDK])
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Could not find a suitable Build JDK])
|
||||
fi
|
||||
|
||||
AC_SUBST(CREATE_BUILDJDK)
|
||||
AC_SUBST(BUILD_JDK)
|
||||
AC_SUBST(EXTERNAL_BUILDJDK)
|
||||
AC_SUBST(EXTERNAL_BUILDJDK_PATH)
|
||||
])
|
||||
|
||||
# The docs-reference JDK is used to run javadoc for the docs-reference targets.
|
||||
|
||||
@ -44,7 +44,3 @@ JAVAC_CMD := $(FIXPATH) $(BOOT_JDK)/bin/javac
|
||||
JAR_CMD := $(FIXPATH) $(BOOT_JDK)/bin/jar
|
||||
# The bootcycle JVM arguments may differ from the original boot jdk.
|
||||
JAVA_FLAGS_BIG := @BOOTCYCLE_JVM_ARGS_BIG@
|
||||
# Any CDS settings generated for the bootjdk are invalid in the bootcycle build.
|
||||
# By filtering out those JVM args, the bootcycle JVM will use its default
|
||||
# settings for CDS.
|
||||
JAVA_FLAGS := $(filter-out -XX:SharedArchiveFile% -Xshare%, $(JAVA_FLAGS))
|
||||
|
||||
@ -37,56 +37,25 @@ AC_DEFUN([FLAGS_SETUP_SHARED_LIBS],
|
||||
if test "x$TOOLCHAIN_TYPE" = xgcc; then
|
||||
# Default works for linux, might work on other platforms as well.
|
||||
SHARED_LIBRARY_FLAGS='-shared'
|
||||
# --disable-new-dtags forces use of RPATH instead of RUNPATH for rpaths.
|
||||
# This protects internal library dependencies within the JDK from being
|
||||
# overridden using LD_LIBRARY_PATH. See JDK-8326891 for more information.
|
||||
SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1 -Wl,--disable-new-dtags'
|
||||
SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN"
|
||||
SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1'
|
||||
|
||||
elif test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
||||
# Linking is different on MacOSX
|
||||
SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0"
|
||||
SET_EXECUTABLE_ORIGIN='-Wl,-rpath,@loader_path$(or [$]1,/.)'
|
||||
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
|
||||
SET_SHARED_LIBRARY_NAME='-Wl,-install_name,@rpath/[$]1'
|
||||
|
||||
elif test "x$OPENJDK_TARGET_OS" = xaix; then
|
||||
# Linking is different on aix
|
||||
SHARED_LIBRARY_FLAGS="-shared -Wl,-bM:SRE -Wl,-bnoentry"
|
||||
SET_EXECUTABLE_ORIGIN=""
|
||||
SET_SHARED_LIBRARY_ORIGIN=''
|
||||
SET_SHARED_LIBRARY_NAME=''
|
||||
|
||||
else
|
||||
# Default works for linux, might work on other platforms as well.
|
||||
SHARED_LIBRARY_FLAGS='-shared'
|
||||
SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1'
|
||||
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
SET_EXECUTABLE_ORIGIN="$SET_EXECUTABLE_ORIGIN -Wl,--disable-new-dtags"
|
||||
fi
|
||||
SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]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" = xmicrosoft; then
|
||||
SHARED_LIBRARY_FLAGS="-dll"
|
||||
SET_EXECUTABLE_ORIGIN=''
|
||||
SET_SHARED_LIBRARY_ORIGIN=''
|
||||
SET_SHARED_LIBRARY_NAME=''
|
||||
fi
|
||||
|
||||
AC_SUBST(SET_EXECUTABLE_ORIGIN)
|
||||
AC_SUBST(SET_SHARED_LIBRARY_ORIGIN)
|
||||
AC_SUBST(SET_SHARED_LIBRARY_NAME)
|
||||
AC_SUBST(SHARED_LIBRARY_FLAGS)
|
||||
])
|
||||
|
||||
@ -934,48 +903,6 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
|
||||
IF_FALSE: [$2FDLIBM_CFLAGS=""])
|
||||
fi
|
||||
AC_SUBST($2FDLIBM_CFLAGS)
|
||||
|
||||
# Check whether the compiler supports the Arm C Language Extensions (ACLE)
|
||||
# for SVE. Set SVE_CFLAGS to -march=armv8-a+sve if it does.
|
||||
# ACLE and this flag are required to build the aarch64 SVE related functions in
|
||||
# libvectormath. Apple Silicon does not support SVE; use macOS as a proxy for
|
||||
# that check.
|
||||
if test "x$OPENJDK_TARGET_CPU" = "xaarch64" && test "x$OPENJDK_TARGET_OS" = "xlinux"; then
|
||||
if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
AC_LANG_PUSH(C)
|
||||
OLD_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -march=armv8-a+sve"
|
||||
AC_MSG_CHECKING([if Arm SVE ACLE is supported])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <arm_sve.h>],
|
||||
[
|
||||
svint32_t r = svdup_n_s32(1);
|
||||
return 0;
|
||||
])],
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
$2SVE_CFLAGS="-march=armv8-a+sve"
|
||||
# Switching the initialization mode with gcc from 'pattern' to 'zero'
|
||||
# avoids the use of unsupported `__builtin_clear_padding` for variable
|
||||
# length aggregates
|
||||
if test "x$DEBUG_LEVEL" != xrelease && test "x$TOOLCHAIN_TYPE" = xgcc ; then
|
||||
INIT_ZERO_FLAG="-ftrivial-auto-var-init=zero"
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$INIT_ZERO_FLAG],
|
||||
IF_TRUE: [
|
||||
$2SVE_CFLAGS="${$2SVE_CFLAGS} $INIT_ZERO_FLAG"
|
||||
]
|
||||
)
|
||||
fi
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT([no])
|
||||
$2SVE_CFLAGS=""
|
||||
]
|
||||
)
|
||||
CFLAGS="$OLD_CFLAGS"
|
||||
AC_LANG_POP(C)
|
||||
fi
|
||||
fi
|
||||
AC_SUBST($2SVE_CFLAGS)
|
||||
])
|
||||
|
||||
AC_DEFUN_ONCE([FLAGS_SETUP_BRANCH_PROTECTION],
|
||||
|
||||
@ -79,7 +79,7 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
|
||||
fi
|
||||
if test "x$OPENJDK_TARGET_OS" = xaix; then
|
||||
BASIC_LDFLAGS="-Wl,-b64 -Wl,-brtl -Wl,-bnorwexec -Wl,-blibpath:/usr/lib:lib -Wl,-bnoexpall \
|
||||
-Wl,-bernotok -Wl,-bdatapsize:64k -Wl,-btextpsize:64k -Wl,-bstackpsize:64k"
|
||||
-Wl,-bernotok -Wl,-bcdtors:mbr::s -Wl,-bdatapsize:64k -Wl,-btextpsize:64k -Wl,-bstackpsize:64k"
|
||||
BASIC_LDFLAGS_JVM_ONLY="$BASIC_LDFLAGS_JVM_ONLY -Wl,-lC_r -Wl,-bbigtoc"
|
||||
fi
|
||||
|
||||
@ -98,7 +98,7 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
|
||||
|
||||
# Setup OS-dependent LDFLAGS
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx && test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
# FIXME: We should really generalize SET_SHARED_LIBRARY_ORIGIN instead.
|
||||
# FIXME: We should really generalize SetSharedLibraryOrigin instead.
|
||||
OS_LDFLAGS_JVM_ONLY="-Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
|
||||
OS_LDFLAGS="-mmacosx-version-min=$MACOSX_VERSION_MIN -Wl,-reproducible"
|
||||
fi
|
||||
|
||||
@ -107,6 +107,62 @@ AC_DEFUN([FLAGS_SETUP_NMFLAGS],
|
||||
AC_SUBST(NMFLAGS)
|
||||
])
|
||||
|
||||
# Check whether the compiler supports the Arm C Language Extensions (ACLE)
|
||||
# for SVE. Set SVE_CFLAGS to -march=armv8-a+sve if it does.
|
||||
# ACLE and this flag are required to build the aarch64 SVE related functions
|
||||
# in libvectormath.
|
||||
AC_DEFUN([FLAGS_SETUP_SVE],
|
||||
[
|
||||
AARCH64_SVE_AVAILABLE=false
|
||||
# Apple Silicon does not support SVE; use macOS as a proxy for that check.
|
||||
if test "x$OPENJDK_TARGET_CPU" = "xaarch64" && test "x$OPENJDK_TARGET_OS" = "xlinux"; then
|
||||
if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
# check the compiler and binutils support sve or not
|
||||
AC_MSG_CHECKING([if Arm SVE ACLE is supported])
|
||||
AC_LANG_PUSH([C])
|
||||
saved_cflags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -march=armv8-a+sve $CFLAGS_WARNINGS_ARE_ERRORS ARG_ARGUMENT"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||
[
|
||||
#include <arm_sve.h>
|
||||
svfloat64_t a() {}
|
||||
],
|
||||
[
|
||||
svint32_t r = svdup_n_s32(1)
|
||||
])],
|
||||
[
|
||||
AARCH64_SVE_AVAILABLE=true
|
||||
]
|
||||
)
|
||||
CFLAGS="$saved_cflags"
|
||||
AC_LANG_POP([C])
|
||||
AC_MSG_RESULT([$AARCH64_SVE_AVAILABLE])
|
||||
fi
|
||||
fi
|
||||
|
||||
UTIL_ARG_ENABLE(NAME: aarch64-sve, DEFAULT: auto,
|
||||
RESULT: AARCH64_SVE_ENABLED,
|
||||
DESC: [Use SVE when compiling libsleef],
|
||||
AVAILABLE: $AARCH64_SVE_AVAILABLE)
|
||||
SVE_CFLAGS=""
|
||||
if test "x$AARCH64_SVE_ENABLED" = xtrue; then
|
||||
SVE_CFLAGS="-march=armv8-a+sve"
|
||||
# Switching the initialization mode with gcc from 'pattern' to 'zero'
|
||||
# avoids the use of unsupported `__builtin_clear_padding` for variable
|
||||
# length aggregates
|
||||
if test "x$DEBUG_LEVEL" != xrelease && test "x$TOOLCHAIN_TYPE" = xgcc ; then
|
||||
AC_MSG_CHECKING([Switching the initialization mode with gcc from pattern to zero])
|
||||
INIT_ZERO_FLAG="-ftrivial-auto-var-init=zero"
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$INIT_ZERO_FLAG],
|
||||
IF_TRUE: [
|
||||
SVE_CFLAGS="${SVE_CFLAGS} $INIT_ZERO_FLAG"
|
||||
]
|
||||
)
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(SVE_CFLAGS)
|
||||
])
|
||||
|
||||
################################################################################
|
||||
# platform independent
|
||||
AC_DEFUN([FLAGS_SETUP_ASFLAGS],
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2025, 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
|
||||
@ -319,16 +319,10 @@ AC_DEFUN_ONCE([FLAGS_PRE_TOOLCHAIN],
|
||||
AC_DEFUN([FLAGS_SETUP_TOOLCHAIN_CONTROL],
|
||||
[
|
||||
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||
CC_OUT_OPTION=-Fo
|
||||
if test "x$OPENJDK_TARGET_CPU" != xaarch64; then
|
||||
AS_NON_ASM_EXTENSION_OPTION=-Ta
|
||||
fi
|
||||
else
|
||||
# The option used to specify the target .o,.a or .so file.
|
||||
# When compiling, how to specify the to be created object file.
|
||||
CC_OUT_OPTION='-o$(SPACE)'
|
||||
fi
|
||||
AC_SUBST(CC_OUT_OPTION)
|
||||
AC_SUBST(AS_NON_ASM_EXTENSION_OPTION)
|
||||
|
||||
# Generate make dependency files
|
||||
@ -374,6 +368,7 @@ AC_DEFUN([FLAGS_SETUP_FLAGS],
|
||||
FLAGS_SETUP_RCFLAGS
|
||||
FLAGS_SETUP_NMFLAGS
|
||||
|
||||
FLAGS_SETUP_SVE
|
||||
FLAGS_SETUP_ASFLAGS
|
||||
FLAGS_SETUP_ASFLAGS_CPU_DEP([TARGET])
|
||||
FLAGS_SETUP_ASFLAGS_CPU_DEP([BUILD], [OPENJDK_BUILD_])
|
||||
|
||||
@ -565,9 +565,14 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_UNDEFINED_BEHAVIOR_SANITIZER],
|
||||
# with an additional define LLVM_SYMBOLIZER, which we set here.
|
||||
# To calculate the correct llvm_symbolizer path we can use the location of the compiler, because
|
||||
# their relation is fixed.
|
||||
# In the ubsan case we have to link every binary with the C++-compiler as linker, because inherently
|
||||
# the C-Compiler and the C++-compiler used as linker provide a different set of ubsan exports.
|
||||
# Linking an executable with the C-compiler and one of its shared libraries with the C++-compiler
|
||||
# leeds to unresolved symbols.
|
||||
if test "x$TOOLCHAIN_TYPE" = "xclang" && test "x$OPENJDK_TARGET_OS" = "xaix"; then
|
||||
UBSAN_CFLAGS="$UBSAN_CFLAGS -fno-sanitize=function,vptr -DLLVM_SYMBOLIZER=$(dirname $(dirname $CC))/tools/ibm-llvm-symbolizer"
|
||||
UBSAN_LDFLAGS="$UBSAN_LDFLAGS -fno-sanitize=function,vptr -Wl,-bbigtoc"
|
||||
UBSAN_CFLAGS="$UBSAN_CFLAGS -DLLVM_SYMBOLIZER=$(dirname $(dirname $CC))/tools/ibm-llvm-symbolizer"
|
||||
UBSAN_LDFLAGS="$UBSAN_LDFLAGS -Wl,-bbigtoc"
|
||||
LD="$LDCXX"
|
||||
fi
|
||||
UTIL_ARG_ENABLE(NAME: ubsan, DEFAULT: false, RESULT: UBSAN_ENABLED,
|
||||
DESC: [enable UndefinedBehaviorSanitizer],
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
################################################################################
|
||||
|
||||
# Minimum supported versions
|
||||
JTREG_MINIMUM_VERSION=7.5.2
|
||||
JTREG_MINIMUM_VERSION=8.1
|
||||
GTEST_MINIMUM_VERSION=1.14.0
|
||||
|
||||
################################################################################
|
||||
|
||||
@ -136,12 +136,8 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES],
|
||||
BASIC_JVM_LIBS="$BASIC_JVM_LIBS $LIBPTHREAD"
|
||||
fi
|
||||
|
||||
# librt for legacy clock_gettime
|
||||
# librt - for timers (timer_* functions)
|
||||
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
# Hotspot needs to link librt to get the clock_* functions.
|
||||
# But once our supported minimum build and runtime platform
|
||||
# has glibc 2.17, this can be removed as the functions are
|
||||
# in libc.
|
||||
BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lrt"
|
||||
fi
|
||||
|
||||
|
||||
@ -386,9 +386,22 @@ CAPSTONE_ARCH_AARCH64_NAME := @CAPSTONE_ARCH_AARCH64_NAME@
|
||||
# it in sync.
|
||||
BOOT_JDK := @BOOT_JDK@
|
||||
|
||||
BUILD_JDK := @BUILD_JDK@
|
||||
CREATE_BUILDJDK := @CREATE_BUILDJDK@
|
||||
EXTERNAL_BUILDJDK := @EXTERNAL_BUILDJDK@
|
||||
EXTERNAL_BUILDJDK_PATH := @EXTERNAL_BUILDJDK_PATH@
|
||||
|
||||
ifneq ($(EXTERNAL_BUILDJDK_PATH), )
|
||||
EXTERNAL_BUILDJDK := true
|
||||
CREATE_BUILDJDK := false
|
||||
BUILD_JDK := $(EXTERNAL_BUILDJDK_PATH)
|
||||
else
|
||||
EXTERNAL_BUILDJDK := false
|
||||
ifeq ($(COMPILE_TYPE), cross)
|
||||
CREATE_BUILDJDK := true
|
||||
BUILD_JDK := $(BUILDJDK_OUTPUTDIR)/jdk
|
||||
else
|
||||
CREATE_BUILDJDK := false
|
||||
BUILD_JDK := $(JDK_OUTPUTDIR)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Whether the boot jdk jar supports --date=TIMESTAMP
|
||||
BOOT_JDK_JAR_SUPPORTS_DATE := @BOOT_JDK_JAR_SUPPORTS_DATE@
|
||||
@ -491,7 +504,6 @@ CXX_VERSION_NUMBER := @CXX_VERSION_NUMBER@
|
||||
# Legacy support
|
||||
HOTSPOT_TOOLCHAIN_TYPE := @HOTSPOT_TOOLCHAIN_TYPE@
|
||||
|
||||
CC_OUT_OPTION := @CC_OUT_OPTION@
|
||||
AS_NON_ASM_EXTENSION_OPTION := @AS_NON_ASM_EXTENSION_OPTION@
|
||||
|
||||
# Flags used for overriding the default opt setting for a C/C++ source file.
|
||||
@ -624,17 +636,8 @@ ASFLAGS_DEBUG_SYMBOLS := @ASFLAGS_DEBUG_SYMBOLS@
|
||||
# Compress (or not) jars
|
||||
COMPRESS_JARS := @COMPRESS_JARS@
|
||||
|
||||
# Options to linker to specify the library name.
|
||||
# (Note absence of := assignment, because we do not want to evaluate the macro body here)
|
||||
SET_SHARED_LIBRARY_NAME = @SET_SHARED_LIBRARY_NAME@
|
||||
|
||||
SHARED_LIBRARY_FLAGS := @SHARED_LIBRARY_FLAGS@
|
||||
|
||||
# Set origin using the linker, ie use the relative path to the dependent library to find the dependencies.
|
||||
# (Note absence of := assignment, because we do not want to evaluate the macro body here)
|
||||
SET_SHARED_LIBRARY_ORIGIN = @SET_SHARED_LIBRARY_ORIGIN@
|
||||
SET_EXECUTABLE_ORIGIN = @SET_EXECUTABLE_ORIGIN@
|
||||
|
||||
LIBRARY_PREFIX := @LIBRARY_PREFIX@
|
||||
SHARED_LIBRARY_SUFFIX := @SHARED_LIBRARY_SUFFIX@
|
||||
STATIC_LIBRARY_SUFFIX := @STATIC_LIBRARY_SUFFIX@
|
||||
@ -657,8 +660,8 @@ JAVA_CMD := @JAVA@
|
||||
JAVAC_CMD := @JAVAC@
|
||||
JAVADOC_CMD := @JAVADOC@
|
||||
JAR_CMD := @JAR@
|
||||
JLINK_CMD := @JLINK@
|
||||
JMOD_CMD := @JMOD@
|
||||
JLINK_CMD := @FIXPATH@ $(BUILD_JDK)/bin/jlink
|
||||
JMOD_CMD := @FIXPATH@ $(BUILD_JDK)/bin/jmod
|
||||
# These variables are meant to be used. They are defined with = instead of := to make
|
||||
# it possible to override only the *_CMD variables.
|
||||
JAVA = $(JAVA_CMD) $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
|
||||
|
||||
@ -148,9 +148,12 @@ define SetupExecuteBody
|
||||
$1_INFO := Running commands for $1
|
||||
endif
|
||||
|
||||
$1_VARDEPS := $$($1_COMMAND) $$($1_PRE_COMMAND) $$($1_POST_COMMAND)
|
||||
$1_VARDEPS_FILE := $$(call DependOnVariable, $1_VARDEPS, $$($1_BASE)_exec.vardeps)
|
||||
|
||||
ifneq ($$($1_PRE_COMMAND), )
|
||||
|
||||
$$($1_PRE_MARKER): $$($1_DEPS)
|
||||
$$($1_PRE_MARKER): $$($1_DEPS) $$($1_VARDEPS_FILE)
|
||||
ifneq ($$($1_WARN), )
|
||||
$$(call LogWarn, $$($1_WARN))
|
||||
endif
|
||||
@ -176,7 +179,7 @@ define SetupExecuteBody
|
||||
|
||||
$1 := $$($1_PRE_MARKER) $$($1_EXEC_RESULT)
|
||||
else
|
||||
$$($1_EXEC_RESULT): $$($1_DEPS)
|
||||
$$($1_EXEC_RESULT): $$($1_DEPS) $$($1_VARDEPS_FILE)
|
||||
ifneq ($$($1_WARN), )
|
||||
$$(call LogWarn, $$($1_WARN))
|
||||
endif
|
||||
|
||||
@ -30,6 +30,47 @@ ifeq ($(INCLUDE), true)
|
||||
|
||||
include NativeCompilation.gmk
|
||||
|
||||
ifeq ($(call isCompiler, gcc), true)
|
||||
# --disable-new-dtags forces use of RPATH instead of RUNPATH for rpaths.
|
||||
# This protects internal library dependencies within the JDK from being
|
||||
# overridden using LD_LIBRARY_PATH. See JDK-8326891 for more information.
|
||||
SetExecutableOrigin = \
|
||||
-Wl,-rpath,\$(DOLLAR)ORIGIN$1 -Wl,--disable-new-dtags
|
||||
SetSharedLibraryOrigin = \
|
||||
-Wl,-z,origin -Wl,-rpath,\$(DOLLAR)ORIGIN$1 -Wl,--disable-new-dtags
|
||||
else ifeq ($(call isCompiler, clang), true)
|
||||
ifeq ($(call isTargetOs, macosx), true)
|
||||
SetExecutableOrigin = \
|
||||
-Wl,-rpath,@loader_path$(or $1,/.)
|
||||
SetSharedLibraryOrigin = \
|
||||
-Wl,-rpath,@loader_path$(or $1,/.)
|
||||
else ifeq ($(call isTargetOs, aix), true)
|
||||
SetExecutableOrigin =
|
||||
SetSharedLibraryOrigin =
|
||||
else
|
||||
ifeq ($(call isTargetOs, linux), true)
|
||||
SetExecutableOrigin = \
|
||||
-Wl,-rpath,\$(DOLLAR)ORIGIN$1 -Wl,--disable-new-dtags
|
||||
else
|
||||
SetExecutableOrigin = \
|
||||
-Wl,-rpath,\$(DOLLAR)ORIGIN$1
|
||||
endif
|
||||
|
||||
ifeq ($(call isTargetOs, arm), true)
|
||||
SetSharedLibraryOrigin = \
|
||||
-Wl,-rpath,\$(DOLLAR)ORIGIN$1
|
||||
else
|
||||
SetSharedLibraryOrigin = \
|
||||
-Wl,-z,origin -Wl,-rpath,\$(DOLLAR)ORIGIN$1
|
||||
endif
|
||||
endif
|
||||
else ifeq ($(call isCompiler, microsoft), true)
|
||||
SetExecutableOrigin =
|
||||
SetSharedLibraryOrigin =
|
||||
else
|
||||
$(error Unknown toolchain)
|
||||
endif
|
||||
|
||||
FindSrcDirsForComponent += \
|
||||
$(call uniq, $(wildcard \
|
||||
$(TOPDIR)/src/$(strip $1)/$(OPENJDK_TARGET_OS)/native/$(strip $2) \
|
||||
@ -444,9 +485,9 @@ define SetupJdkNativeCompilationBody
|
||||
|
||||
ifneq ($$($1_LD_SET_ORIGIN), false)
|
||||
ifeq ($$($1_TYPE), EXECUTABLE)
|
||||
$1_LDFLAGS += $$(call SET_EXECUTABLE_ORIGIN)
|
||||
$1_LDFLAGS += $$(call SetExecutableOrigin)
|
||||
else
|
||||
$1_LDFLAGS += $$(call SET_SHARED_LIBRARY_ORIGIN)
|
||||
$1_LDFLAGS += $$(call SetSharedLibraryOrigin)
|
||||
endif
|
||||
endif
|
||||
# APPEND_LDFLAGS, if it exists, must be set after the origin flags
|
||||
|
||||
@ -156,8 +156,8 @@ define SetupBuildLauncherBody
|
||||
DISABLED_WARNINGS_gcc := unused-function unused-variable, \
|
||||
DISABLED_WARNINGS_clang := unused-function, \
|
||||
LDFLAGS := $$($1_LDFLAGS), \
|
||||
LDFLAGS_linux := $$(call SET_EXECUTABLE_ORIGIN,/../lib), \
|
||||
LDFLAGS_macosx := $$(call SET_EXECUTABLE_ORIGIN,/../lib), \
|
||||
LDFLAGS_linux := $$(call SetExecutableOrigin,/../lib), \
|
||||
LDFLAGS_macosx := $$(call SetExecutableOrigin,/../lib), \
|
||||
LDFLAGS_FILTER_OUT := $$($1_LDFLAGS_FILTER_OUT), \
|
||||
JDK_LIBS := $$($1_JDK_LIBS), \
|
||||
JDK_LIBS_windows := $$($1_JDK_LIBS_windows), \
|
||||
|
||||
@ -93,6 +93,14 @@ DEPENDENCY_TARGET_SED_PATTERN := \
|
||||
-e 's/$$$$/ :/' \
|
||||
#
|
||||
|
||||
################################################################################
|
||||
# Setup compiler-specific argument to specify output file
|
||||
ifeq ($(call isCompiler, microsoft), true)
|
||||
CC_OUT_OPTION := -Fo
|
||||
else
|
||||
CC_OUT_OPTION := -o$(SPACE)
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Create the recipe needed to compile a single native source file.
|
||||
#
|
||||
@ -334,7 +342,7 @@ define CreateWindowsResourceFile
|
||||
$$(call LogInfo, Compiling resource $$(notdir $$($1_VERSIONINFO_RESOURCE)) (for $$($1_BASENAME)))
|
||||
$$(call MakeDir, $$(@D) $$($1_OBJECT_DIR))
|
||||
$$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \
|
||||
$$($1_RC) $$($1_RCFLAGS) $$($1_SYSROOT_CFLAGS) $(CC_OUT_OPTION)$$@ \
|
||||
$$($1_RC) $$($1_RCFLAGS) $$($1_SYSROOT_CFLAGS) -Fo$$@ \
|
||||
$$($1_VERSIONINFO_RESOURCE) 2>&1 ))
|
||||
# Windows RC compiler does not support -showIncludes, so we mis-use CL
|
||||
# for this. Filter out RC specific arguments that are unknown to CL.
|
||||
@ -344,7 +352,7 @@ define CreateWindowsResourceFile
|
||||
$$(call ExecuteWithLog, $$($1_RES_DEPS_FILE)$(OBJ_SUFFIX), \
|
||||
$$($1_CC) $$(filter-out -l%, $$($1_RCFLAGS)) \
|
||||
$$($1_SYSROOT_CFLAGS) -showIncludes -nologo -TC \
|
||||
$(CC_OUT_OPTION)$$($1_RES_DEPS_FILE)$(OBJ_SUFFIX) -P -Fi$$($1_RES_DEPS_FILE).pp \
|
||||
-Fo$$($1_RES_DEPS_FILE)$(OBJ_SUFFIX) -P -Fi$$($1_RES_DEPS_FILE).pp \
|
||||
$$($1_VERSIONINFO_RESOURCE)) 2>&1 \
|
||||
| $(TR) -d '\r' | $(GREP) -v -e "^Note: including file:" \
|
||||
-e "^$$(notdir $$($1_VERSIONINFO_RESOURCE))$$$$" || test "$$$$?" = "1" ; \
|
||||
|
||||
@ -50,6 +50,26 @@ GetEntitlementsFile = \
|
||||
$(if $(wildcard $f), $f, $(DEFAULT_ENTITLEMENTS_FILE)) \
|
||||
)
|
||||
|
||||
ifeq ($(call isCompiler, gcc), true)
|
||||
SetSharedLibraryName = \
|
||||
-Wl,-soname=$1
|
||||
else ifeq ($(call isCompiler, clang), true)
|
||||
ifeq ($(call isTargetOs, macosx), true)
|
||||
SetSharedLibraryName = \
|
||||
-Wl,-install_name,@rpath/$1
|
||||
else ifeq ($(call isTargetOs, aix), true)
|
||||
SetSharedLibraryName =
|
||||
else
|
||||
# Default works for linux, might work on other platforms as well.
|
||||
SetSharedLibraryName = \
|
||||
-Wl,-soname=$1
|
||||
endif
|
||||
else ifeq ($(call isCompiler, microsoft), true)
|
||||
SetSharedLibraryName =
|
||||
else
|
||||
$(error Unknown toolchain)
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
define SetupLinking
|
||||
# Unless specifically set, stripping should only happen if symbols are also
|
||||
@ -131,7 +151,7 @@ define CreateDynamicLibraryOrExecutable
|
||||
# A shared dynamic library or an executable binary has been specified
|
||||
ifeq ($$($1_TYPE), LIBRARY)
|
||||
# Generating a dynamic library.
|
||||
$1_EXTRA_LDFLAGS += $$(call SET_SHARED_LIBRARY_NAME,$$($1_BASENAME))
|
||||
$1_EXTRA_LDFLAGS += $$(call SetSharedLibraryName,$$($1_BASENAME))
|
||||
endif
|
||||
|
||||
ifeq ($(MACOSX_CODESIGN_MODE), hardened)
|
||||
|
||||
@ -26,24 +26,24 @@
|
||||
# Versions and download locations for dependencies used by GitHub Actions (GHA)
|
||||
|
||||
GTEST_VERSION=1.14.0
|
||||
JTREG_VERSION=7.5.2+1
|
||||
JTREG_VERSION=8.1+1
|
||||
|
||||
LINUX_X64_BOOT_JDK_EXT=tar.gz
|
||||
LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_linux-x64_bin.tar.gz
|
||||
LINUX_X64_BOOT_JDK_SHA256=88b090fa80c6c1d084ec9a755233967458788e2c0777ae2e172230c5c692d7ef
|
||||
LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk25/bd75d5f9689641da8e1daabeccb5528b/36/GPL/openjdk-25_linux-x64_bin.tar.gz
|
||||
LINUX_X64_BOOT_JDK_SHA256=59cdcaf255add4721de38eb411d4ecfe779356b61fb671aee63c7dec78054c2b
|
||||
|
||||
ALPINE_LINUX_X64_BOOT_JDK_EXT=tar.gz
|
||||
ALPINE_LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin24-binaries/releases/download/jdk-24%2B36/OpenJDK24U-jdk_x64_alpine-linux_hotspot_24_36.tar.gz
|
||||
ALPINE_LINUX_X64_BOOT_JDK_SHA256=a642608f0da78344ee6812fb1490b8bc1d7ad5a18064c70994d6f330568c51cb
|
||||
ALPINE_LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25%2B36/OpenJDK25U-jdk_x64_alpine-linux_hotspot_25_36.tar.gz
|
||||
ALPINE_LINUX_X64_BOOT_JDK_SHA256=637e47474d411ed86134f413af7d5fef4180ddb0bf556347b7e74a88cf8904c8
|
||||
|
||||
MACOS_AARCH64_BOOT_JDK_EXT=tar.gz
|
||||
MACOS_AARCH64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_macos-aarch64_bin.tar.gz
|
||||
MACOS_AARCH64_BOOT_JDK_SHA256=f7133238a12714a62c5ad2bd4da6741130be1a82512065da9ca23dee26b2d3d3
|
||||
MACOS_AARCH64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk25/bd75d5f9689641da8e1daabeccb5528b/36/GPL/openjdk-25_macos-aarch64_bin.tar.gz
|
||||
MACOS_AARCH64_BOOT_JDK_SHA256=2006337bf326fdfdf6117081751ba38c1c8706d63419ecac7ff102ff7c776876
|
||||
|
||||
MACOS_X64_BOOT_JDK_EXT=tar.gz
|
||||
MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_macos-x64_bin.tar.gz
|
||||
MACOS_X64_BOOT_JDK_SHA256=6bbfb1d01741cbe55ab90299cb91464b695de9a3ace85c15131aa2f50292f321
|
||||
MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk25/bd75d5f9689641da8e1daabeccb5528b/36/GPL/openjdk-25_macos-x64_bin.tar.gz
|
||||
MACOS_X64_BOOT_JDK_SHA256=47482ad9888991ecac9b2bcc131e2b53ff78aff275104cef85f66252308e8a09
|
||||
|
||||
WINDOWS_X64_BOOT_JDK_EXT=zip
|
||||
WINDOWS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_windows-x64_bin.zip
|
||||
WINDOWS_X64_BOOT_JDK_SHA256=11d1d9f6ac272d5361c8a0bef01894364081c7fb1a6914c2ad2fc312ae83d63b
|
||||
WINDOWS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk25/bd75d5f9689641da8e1daabeccb5528b/36/GPL/openjdk-25_windows-x64_bin.zip
|
||||
WINDOWS_X64_BOOT_JDK_SHA256=85bcc178461e2cb3c549ab9ca9dfa73afd54c09a175d6510d0884071867137d3
|
||||
|
||||
@ -387,8 +387,8 @@ var getJibProfilesCommon = function (input, data) {
|
||||
};
|
||||
};
|
||||
|
||||
common.boot_jdk_version = "24";
|
||||
common.boot_jdk_build_number = "36";
|
||||
common.boot_jdk_version = "25";
|
||||
common.boot_jdk_build_number = "37";
|
||||
common.boot_jdk_home = input.get("boot_jdk", "install_path") + "/jdk-"
|
||||
+ common.boot_jdk_version
|
||||
+ (input.build_os == "macosx" ? ".jdk/Contents/Home" : "");
|
||||
@ -1174,9 +1174,9 @@ var getJibProfilesDependencies = function (input, common) {
|
||||
jtreg: {
|
||||
server: "jpg",
|
||||
product: "jtreg",
|
||||
version: "7.5.2",
|
||||
version: "8.1",
|
||||
build_number: "1",
|
||||
file: "bundles/jtreg-7.5.2+1.zip",
|
||||
file: "bundles/jtreg-8.1+1.zip",
|
||||
environment_name: "JT_HOME",
|
||||
environment_path: input.get("jtreg", "home_path") + "/bin",
|
||||
configure_args: "--with-jtreg=" + input.get("jtreg", "home_path"),
|
||||
|
||||
@ -37,6 +37,6 @@ DEFAULT_VERSION_DATE=2026-03-17
|
||||
DEFAULT_VERSION_CLASSFILE_MAJOR=70 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
||||
DEFAULT_VERSION_CLASSFILE_MINOR=0
|
||||
DEFAULT_VERSION_DOCS_API_SINCE=11
|
||||
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="24 25 26"
|
||||
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="25 26"
|
||||
DEFAULT_JDK_SOURCE_TARGET_VERSION=26
|
||||
DEFAULT_PROMOTED_VERSION_PRE=ea
|
||||
|
||||
@ -32,11 +32,6 @@
|
||||
547d 92ca
|
||||
53da 9b7e
|
||||
446e f86f
|
||||
#
|
||||
# we should use this one instead of the 4260<-ff0d
|
||||
#4260 2212
|
||||
4260 ff0d
|
||||
#
|
||||
426A 00A6
|
||||
43A1 301C
|
||||
444A 2014
|
||||
|
||||
@ -25,13 +25,6 @@
|
||||
# 4260 <--> 2212
|
||||
# 426A <--> 00A6
|
||||
#
|
||||
# Warning:
|
||||
# "our old" implementation seems agree with above "new" mappings
|
||||
# except the entries 4260 <-> 2212. To keep the "compatbility"
|
||||
# with the "old" implementation, I changed the entries "temporarily"
|
||||
# 4260 <-> 2212
|
||||
# 4260 <- ff0d
|
||||
#
|
||||
00 0000
|
||||
01 0001
|
||||
02 0002
|
||||
@ -407,8 +400,7 @@ FF 009F
|
||||
425D FF09
|
||||
425E FF1B
|
||||
425F FFE2
|
||||
#4260 FF0D
|
||||
4260 2212
|
||||
4260 FF0D
|
||||
4261 FF0F
|
||||
426A FFE4
|
||||
426B FF0C
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -57,61 +57,61 @@
|
||||
|
||||
COMMA := ,
|
||||
|
||||
os := $(shell uname -o)
|
||||
cpu := $(shell uname -p)
|
||||
OS := $(shell uname -o)
|
||||
CPU := $(shell uname -m)
|
||||
|
||||
# Figure out what platform this is building on.
|
||||
me := $(cpu)-$(if $(findstring Linux,$(os)),linux-gnu)
|
||||
ME := $(CPU)-$(if $(findstring Linux,$(OS)),linux-gnu)
|
||||
|
||||
$(info Building on platform $(me))
|
||||
$(info Building on platform $(ME))
|
||||
|
||||
#
|
||||
# By default just build for the current platform, which is assumed to be Linux
|
||||
#
|
||||
ifeq ($(TARGETS), )
|
||||
platforms := $(me)
|
||||
host_platforms := $(platforms)
|
||||
PLATFORMS := $(ME)
|
||||
HOST_PLATFORMS := $(PLATFORMS)
|
||||
else
|
||||
platforms := $(subst $(COMMA), , $(TARGETS))
|
||||
host_platforms := $(me)
|
||||
PLATFORMS := $(subst $(COMMA), , $(TARGETS))
|
||||
HOST_PLATFORMS := $(ME)
|
||||
endif
|
||||
target_platforms := $(platforms)
|
||||
$(info host_platforms $(host_platforms))
|
||||
$(info target_platforms $(target_platforms))
|
||||
TARGET_PLATFORMS := $(PLATFORMS)
|
||||
$(info HOST_PLATFORMS $(HOST_PLATFORMS))
|
||||
$(info TARGET_PLATFORMS $(TARGET_PLATFORMS))
|
||||
|
||||
all compile : $(platforms)
|
||||
all compile : $(PLATFORMS)
|
||||
|
||||
ifeq ($(SKIP_ME), )
|
||||
$(foreach p,$(filter-out $(me),$(platforms)),$(eval $(p) : $$(me)))
|
||||
$(foreach p,$(filter-out $(ME),$(PLATFORMS)),$(eval $(p) : $$(ME)))
|
||||
endif
|
||||
|
||||
OUTPUT_ROOT = $(abspath ../../build/devkit)
|
||||
RESULT = $(OUTPUT_ROOT)/result
|
||||
|
||||
submakevars = HOST=$@ BUILD=$(me) RESULT=$(RESULT) OUTPUT_ROOT=$(OUTPUT_ROOT)
|
||||
SUBMAKEVARS = HOST=$@ BUILD=$(ME) RESULT=$(RESULT) OUTPUT_ROOT=$(OUTPUT_ROOT)
|
||||
|
||||
$(host_platforms) :
|
||||
$(HOST_PLATFORMS) :
|
||||
@echo 'Building compilers for $@'
|
||||
@echo 'Targets: $(target_platforms)'
|
||||
for p in $(filter $@, $(target_platforms)) $(filter-out $@, $(target_platforms)); do \
|
||||
$(MAKE) -f Tools.gmk download-rpms $(submakevars) \
|
||||
@echo 'Targets: $(TARGET_PLATFORMS)'
|
||||
for p in $(filter $@, $(TARGET_PLATFORMS)) $(filter-out $@, $(TARGET_PLATFORMS)); do \
|
||||
$(MAKE) -f Tools.gmk download-rpms $(SUBMAKEVARS) \
|
||||
TARGET=$$p PREFIX=$(RESULT)/$@-to-$$p && \
|
||||
$(MAKE) -f Tools.gmk all $(submakevars) \
|
||||
$(MAKE) -f Tools.gmk all $(SUBMAKEVARS) \
|
||||
TARGET=$$p PREFIX=$(RESULT)/$@-to-$$p && \
|
||||
$(MAKE) -f Tools.gmk ccache $(submakevars) \
|
||||
$(MAKE) -f Tools.gmk ccache $(SUBMAKEVARS) \
|
||||
TARGET=$@ PREFIX=$(RESULT)/$@-to-$$p || exit 1 ; \
|
||||
done
|
||||
@echo 'All done"'
|
||||
|
||||
today := $(shell date +%Y%m%d)
|
||||
TODAY := $(shell date +%Y%m%d)
|
||||
|
||||
define Mktar
|
||||
$(1)-to-$(2)_tar = $$(RESULT)/sdk-$(1)-to-$(2)-$$(today).tar.gz
|
||||
$(1)-to-$(2)_tar = $$(RESULT)/sdk-$(1)-to-$(2)-$$(TODAY).tar.gz
|
||||
$$($(1)-to-$(2)_tar) : PLATFORM = $(1)-to-$(2)
|
||||
TARFILES += $$($(1)-to-$(2)_tar)
|
||||
endef
|
||||
|
||||
$(foreach p,$(host_platforms),$(foreach t,$(target_platforms),$(eval $(call Mktar,$(p),$(t)))))
|
||||
$(foreach p,$(HOST_PLATFORMS),$(foreach t,$(TARGET_PLATFORMS),$(eval $(call Mktar,$(p),$(t)))))
|
||||
|
||||
tars : all $(TARFILES)
|
||||
onlytars : $(TARFILES)
|
||||
@ -119,9 +119,9 @@ onlytars : $(TARFILES)
|
||||
$(MAKE) -r -f Tars.gmk SRC_DIR=$(RESULT)/$(PLATFORM) TAR_FILE=$@
|
||||
|
||||
clean :
|
||||
rm -rf $(addprefix ../../build/devkit/, result $(host_platforms))
|
||||
rm -rf $(addprefix ../../build/devkit/, result $(HOST_PLATFORMS))
|
||||
dist-clean: clean
|
||||
rm -rf $(addprefix ../../build/devkit/, src download)
|
||||
|
||||
FORCE :
|
||||
.PHONY : all compile tars $(configs) $(host_platforms) clean dist-clean
|
||||
.PHONY : all compile tars $(HOST_PLATFORMS) clean dist-clean
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
# Fix this...
|
||||
#
|
||||
|
||||
uppercase = $(shell echo $1 | tr a-z A-Z)
|
||||
lowercase = $(shell echo $1 | tr A-Z a-z)
|
||||
|
||||
$(info TARGET=$(TARGET))
|
||||
$(info HOST=$(HOST))
|
||||
@ -104,26 +104,48 @@ endif
|
||||
################################################################################
|
||||
# Define external dependencies
|
||||
|
||||
gcc_ver_only := 14.2.0
|
||||
binutils_ver_only := 2.43
|
||||
ccache_ver_only := 4.10.2
|
||||
GNU_BASE_URL := https://ftp.gnu.org/pub/gnu
|
||||
|
||||
BINUTILS_VER_ONLY := 2.43
|
||||
BINUTILS_BASE_URL := $(GNU_BASE_URL)/binutils
|
||||
BINUTILS_SHA512 := 93e063163e54d6a6ee2bd48dc754270bf757a3635b49a702ed6b310e929e94063958512d191e66beaf44275f7ea60865dbde138b624626739679fcc306b133bb
|
||||
|
||||
CCACHE_VER_ONLY := 4.10.2
|
||||
CCACHE_BASE_URL := https://github.com/ccache/ccache/releases/download
|
||||
CCACHE_CMAKE_BASED := 1
|
||||
mpfr_ver_only := 4.2.1
|
||||
gmp_ver_only := 6.3.0
|
||||
mpc_ver_only := 1.3.1
|
||||
gdb_ver_only := 15.2
|
||||
CCACHE_SHA512 := 3815c71d7266c32839acb306763268018acc58b3bbbd9ec79fc101e4217c1720d2ad2f01645bf69168c1c61d27700b6f3bb755cfa82689cca69824f015653f3c
|
||||
|
||||
dependencies := gcc binutils ccache mpfr gmp mpc gdb
|
||||
GCC_VER_ONLY := 14.2.0
|
||||
GCC_BASE_URL := $(GNU_BASE_URL)/gcc
|
||||
GCC_SHA512 := 932bdef0cda94bacedf452ab17f103c0cb511ff2cec55e9112fc0328cbf1d803b42595728ea7b200e0a057c03e85626f937012e49a7515bc5dd256b2bf4bc396
|
||||
|
||||
$(foreach dep,$(dependencies),$(eval $(dep)_ver := $(dep)-$($(dep)_ver_only)))
|
||||
GDB_VER_ONLY := 15.2
|
||||
GDB_BASE_URL := $(GNU_BASE_URL)/gdb
|
||||
GDB_SHA512 := 624007deceb5b15ba89c0725883d1a699fa46714ef30887f3d0165e17c5d65d634671740a135aa69e437d916218abb08cfa2a38ed309ff19d48f51da56b2a8ba
|
||||
|
||||
GCC := http://ftp.gnu.org/pub/gnu/gcc/$(gcc_ver)/$(gcc_ver).tar.xz
|
||||
BINUTILS := http://ftp.gnu.org/pub/gnu/binutils/$(binutils_ver).tar.gz
|
||||
CCACHE := https://github.com/ccache/ccache/releases/download/v$(ccache_ver_only)/$(ccache_ver).tar.xz
|
||||
MPFR := https://www.mpfr.org/$(mpfr_ver)/$(mpfr_ver).tar.bz2
|
||||
GMP := http://ftp.gnu.org/pub/gnu/gmp/$(gmp_ver).tar.bz2
|
||||
MPC := http://ftp.gnu.org/pub/gnu/mpc/$(mpc_ver).tar.gz
|
||||
GDB := http://ftp.gnu.org/gnu/gdb/$(gdb_ver).tar.xz
|
||||
GMP_VER_ONLY := 6.3.0
|
||||
GMP_BASE_URL := $(GNU_BASE_URL)/gmp
|
||||
GMP_SHA512 := e85a0dab5195889948a3462189f0e0598d331d3457612e2d3350799dba2e244316d256f8161df5219538eb003e4b5343f989aaa00f96321559063ed8c8f29fd2
|
||||
|
||||
MPC_VER_ONLY := 1.3.1
|
||||
MPC_BASE_URL := $(GNU_BASE_URL)/mpc
|
||||
MPC_SHA512 := 4bab4ef6076f8c5dfdc99d810b51108ced61ea2942ba0c1c932d624360a5473df20d32b300fc76f2ba4aa2a97e1f275c9fd494a1ba9f07c4cb2ad7ceaeb1ae97
|
||||
|
||||
MPFR_VER_ONLY := 4.2.1
|
||||
MPFR_BASE_URL := https://www.mpfr.org
|
||||
MPFR_SHA512 := bc68c0d755d5446403644833ecbb07e37360beca45f474297b5d5c40926df1efc3e2067eecffdf253f946288bcca39ca89b0613f545d46a9e767d1d4cf358475
|
||||
|
||||
DEPENDENCIES := BINUTILS CCACHE GCC GDB GMP MPC MPFR
|
||||
|
||||
$(foreach dep,$(DEPENDENCIES),$(eval $(dep)_VER := $(call lowercase,$(dep)-$($(dep)_VER_ONLY))))
|
||||
|
||||
BINUTILS_URL := $(BINUTILS_BASE_URL)/$(BINUTILS_VER).tar.xz
|
||||
CCACHE_URL := $(CCACHE_BASE_URL)/v$(CCACHE_VER_ONLY)/$(CCACHE_VER).tar.xz
|
||||
GCC_URL := $(GCC_BASE_URL)/$(GCC_VER)/$(GCC_VER).tar.xz
|
||||
GDB_URL := $(GDB_BASE_URL)/$(GDB_VER).tar.xz
|
||||
GMP_URL := $(GMP_BASE_URL)/$(GMP_VER).tar.xz
|
||||
MPC_URL := $(MPC_BASE_URL)/$(MPC_VER).tar.gz
|
||||
MPFR_URL := $(MPFR_BASE_URL)/$(MPFR_VER)/$(MPFR_VER).tar.xz
|
||||
|
||||
REQUIRED_MIN_MAKE_MAJOR_VERSION := 4
|
||||
ifneq ($(REQUIRED_MIN_MAKE_MAJOR_VERSION),)
|
||||
@ -180,10 +202,10 @@ DOWNLOAD_RPMS := $(DOWNLOAD)/rpms/$(TARGET)-$(LINUX_VERSION)
|
||||
SRCDIR := $(OUTPUT_ROOT)/src
|
||||
|
||||
# Marker file for unpacking rpms
|
||||
rpms := $(SYSROOT)/rpms_unpacked
|
||||
RPMS := $(SYSROOT)/rpms_unpacked
|
||||
|
||||
# Need to patch libs that are linker scripts to use non-absolute paths
|
||||
libs := $(SYSROOT)/libs_patched
|
||||
LIBS := $(SYSROOT)/libs_patched
|
||||
|
||||
################################################################################
|
||||
# Download RPMs
|
||||
@ -198,10 +220,10 @@ download-rpms:
|
||||
################################################################################
|
||||
# Unpack source packages
|
||||
|
||||
# Generate downloading + unpacking of sources.
|
||||
define Download
|
||||
# Generate downloading + checksum verification of sources.
|
||||
define DownloadVerify
|
||||
# Allow override
|
||||
$(1)_DIRNAME ?= $(basename $(basename $(notdir $($(1)))))
|
||||
$(1)_DIRNAME ?= $(basename $(basename $(notdir $($(1)_URL))))
|
||||
$(1)_DIR = $(abspath $(SRCDIR)/$$($(1)_DIRNAME))
|
||||
ifeq ($$($(1)_CMAKE_BASED),)
|
||||
$(1)_CFG = $$($(1)_DIR)/configure
|
||||
@ -212,7 +234,7 @@ define Download
|
||||
$(1)_SRC_MARKER = $$($(1)_DIR)/CMakeLists.txt
|
||||
$(1)_CONFIG = $$(CMAKE_CONFIG) $$($(1)_DIR)
|
||||
endif
|
||||
$(1)_FILE = $(DOWNLOAD)/$(notdir $($(1)))
|
||||
$(1)_FILE = $(DOWNLOAD)/$(notdir $($(1)_URL))
|
||||
|
||||
$$($(1)_SRC_MARKER) : $$($(1)_FILE)
|
||||
mkdir -p $$(SRCDIR)
|
||||
@ -224,11 +246,20 @@ define Download
|
||||
touch $$@
|
||||
|
||||
$$($(1)_FILE) :
|
||||
wget -P $(DOWNLOAD) $$($(1))
|
||||
mkdir -p $$(@D)
|
||||
wget -O - $$($(1)_URL) > $$@.tmp
|
||||
sha512_actual="$$$$(sha512sum $$@.tmp | awk '{ print $$$$1; }')"; \
|
||||
if [ x"$$$${sha512_actual}" != x"$$($(1)_SHA512)" ]; then \
|
||||
echo "Checksum mismatch for $$@.tmp"; \
|
||||
echo " Expected: $$($(1)_SHA512)"; \
|
||||
echo " Actual: $$$${sha512_actual}"; \
|
||||
exit 1; \
|
||||
fi
|
||||
mv $$@.tmp $$@
|
||||
endef
|
||||
|
||||
# Download and unpack all source packages
|
||||
$(foreach dep,$(dependencies),$(eval $(call Download,$(call uppercase,$(dep)))))
|
||||
$(foreach dep,$(DEPENDENCIES),$(eval $(call DownloadVerify,$(dep))))
|
||||
|
||||
################################################################################
|
||||
# Unpack RPMS
|
||||
@ -250,7 +281,7 @@ RPM_FILE_LIST := $(sort $(foreach a, $(RPM_ARCHS), \
|
||||
# Note. For building linux you should install rpm2cpio.
|
||||
define unrpm
|
||||
$(SYSROOT)/$(notdir $(1)).unpacked : $(1)
|
||||
$$(rpms) : $(SYSROOT)/$(notdir $(1)).unpacked
|
||||
$$(RPMS) : $(SYSROOT)/$(notdir $(1)).unpacked
|
||||
endef
|
||||
|
||||
%.unpacked :
|
||||
@ -277,7 +308,7 @@ $(foreach p,$(RPM_FILE_LIST),$(eval $(call unrpm,$(p))))
|
||||
# have it anyway, but just to make sure...
|
||||
# Patch libc.so and libpthread.so to force linking against libraries in sysroot
|
||||
# and not the ones installed on the build machine.
|
||||
$(libs) : $(rpms)
|
||||
$(LIBS) : $(RPMS)
|
||||
@echo Patching libc and pthreads
|
||||
@(for f in `find $(SYSROOT) -name libc.so -o -name libpthread.so`; do \
|
||||
(cat $$f | sed -e 's|/usr/lib64/||g' \
|
||||
@ -293,10 +324,10 @@ $(libs) : $(rpms)
|
||||
# Create links for ffi header files so that they become visible by default when using the
|
||||
# devkit.
|
||||
ifeq ($(ARCH), x86_64)
|
||||
$(SYSROOT)/usr/include/ffi.h: $(rpms)
|
||||
$(SYSROOT)/usr/include/ffi.h: $(RPMS)
|
||||
cd $(@D) && rm -f $(@F) && ln -s ../lib/libffi-*/include/$(@F) .
|
||||
|
||||
$(SYSROOT)/usr/include/ffitarget.h: $(rpms)
|
||||
$(SYSROOT)/usr/include/ffitarget.h: $(RPMS)
|
||||
cd $(@D) && rm -f $(@F) && ln -s ../lib/libffi-*/include/$(@F) .
|
||||
|
||||
SYSROOT_LINKS += $(SYSROOT)/usr/include/ffi.h $(SYSROOT)/usr/include/ffitarget.h
|
||||
@ -305,7 +336,7 @@ endif
|
||||
################################################################################
|
||||
|
||||
# Define marker files for each source package to be compiled
|
||||
$(foreach dep,$(dependencies),$(eval $(dep) = $(TARGETDIR)/$($(dep)_ver).done))
|
||||
$(foreach dep,$(DEPENDENCIES),$(eval $(dep) = $(TARGETDIR)/$($(dep)_VER).done))
|
||||
|
||||
################################################################################
|
||||
|
||||
@ -345,48 +376,48 @@ TOOLS ?= $(call declare_tools,_FOR_TARGET,$(TARGET)-)
|
||||
# CFLAG_<name> to most likely -m32.
|
||||
define mk_bfd
|
||||
$$(info Libs for $(1))
|
||||
$$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \
|
||||
$$(BUILDDIR)/$$(BINUTILS_VER)-$(subst /,-,$(1))/Makefile \
|
||||
: CFLAGS += $$(CFLAGS_$(1))
|
||||
$$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \
|
||||
$$(BUILDDIR)/$$(BINUTILS_VER)-$(subst /,-,$(1))/Makefile \
|
||||
: LIBDIRS = --libdir=$(TARGETDIR)/$(1)
|
||||
|
||||
bfdlib += $$(TARGETDIR)/$$(binutils_ver)-$(subst /,-,$(1)).done
|
||||
bfdmakes += $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile
|
||||
BFDLIB += $$(TARGETDIR)/$$(BINUTILS_VER)-$(subst /,-,$(1)).done
|
||||
BFDMAKES += $$(BUILDDIR)/$$(BINUTILS_VER)-$(subst /,-,$(1))/Makefile
|
||||
endef
|
||||
|
||||
# Create one set of bfds etc for each multilib arch
|
||||
$(foreach l,$(LIBDIRS),$(eval $(call mk_bfd,$(l))))
|
||||
|
||||
# Only build these two libs.
|
||||
$(bfdlib) : MAKECMD = all-libiberty all-bfd
|
||||
$(bfdlib) : INSTALLCMD = install-libiberty install-bfd
|
||||
$(BFDLIB) : MAKECMD = all-libiberty all-bfd
|
||||
$(BFDLIB) : INSTALLCMD = install-libiberty install-bfd
|
||||
|
||||
# Building targets libbfd + libiberty. HOST==TARGET, i.e not
|
||||
# for a cross env.
|
||||
$(bfdmakes) : CONFIG = --target=$(TARGET) \
|
||||
$(BFDMAKES) : CONFIG = --target=$(TARGET) \
|
||||
--host=$(TARGET) --build=$(BUILD) \
|
||||
--prefix=$(TARGETDIR) \
|
||||
--with-sysroot=$(SYSROOT) \
|
||||
$(LIBDIRS)
|
||||
|
||||
$(bfdmakes) : TOOLS = $(call declare_tools,_FOR_TARGET,$(TARGET)-) $(call declare_tools,,$(TARGET)-)
|
||||
$(BFDMAKES) : TOOLS = $(call declare_tools,_FOR_TARGET,$(TARGET)-) $(call declare_tools,,$(TARGET)-)
|
||||
|
||||
################################################################################
|
||||
|
||||
$(gcc) \
|
||||
$(binutils) \
|
||||
$(gmp) \
|
||||
$(mpfr) \
|
||||
$(mpc) \
|
||||
$(bfdmakes) \
|
||||
$(ccache) : ENVS += $(TOOLS)
|
||||
$(GCC) \
|
||||
$(BINUTILS) \
|
||||
$(GMP) \
|
||||
$(MPFR) \
|
||||
$(MPC) \
|
||||
$(BFDMAKES) \
|
||||
$(CCACHE) : ENVS += $(TOOLS)
|
||||
|
||||
# libdir to work around hateful bfd stuff installing into wrong dirs...
|
||||
# ensure we have 64 bit bfd support in the HOST library. I.e our
|
||||
# compiler on i686 will know 64 bit symbols, BUT later
|
||||
# we build just the libs again for TARGET, then with whatever the arch
|
||||
# wants.
|
||||
$(BUILDDIR)/$(binutils_ver)/Makefile : CONFIG += --enable-64-bit-bfd --libdir=$(PREFIX)/$(word 1,$(LIBDIRS))
|
||||
$(BUILDDIR)/$(BINUTILS_VER)/Makefile : CONFIG += --enable-64-bit-bfd --libdir=$(PREFIX)/$(word 1,$(LIBDIRS))
|
||||
|
||||
ifeq ($(filter $(ARCH), s390x riscv64 ppc64le), )
|
||||
# gold compiles but cannot link properly on s390x @ gcc 13.2 and Fedore 41
|
||||
@ -397,8 +428,8 @@ endif
|
||||
|
||||
# Makefile creation. Simply run configure in build dir.
|
||||
# Setting CFLAGS to -O2 generates a much faster ld.
|
||||
$(bfdmakes) \
|
||||
$(BUILDDIR)/$(binutils_ver)/Makefile \
|
||||
$(BFDMAKES) \
|
||||
$(BUILDDIR)/$(BINUTILS_VER)/Makefile \
|
||||
: $(BINUTILS_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
@ -417,7 +448,7 @@ $(BUILDDIR)/$(binutils_ver)/Makefile \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
$(BUILDDIR)/$(mpfr_ver)/Makefile \
|
||||
$(BUILDDIR)/$(MPFR_VER)/Makefile \
|
||||
: $(MPFR_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
@ -432,7 +463,7 @@ $(BUILDDIR)/$(mpfr_ver)/Makefile \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
$(BUILDDIR)/$(gmp_ver)/Makefile \
|
||||
$(BUILDDIR)/$(GMP_VER)/Makefile \
|
||||
: $(GMP_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
@ -449,7 +480,7 @@ $(BUILDDIR)/$(gmp_ver)/Makefile \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
$(BUILDDIR)/$(mpc_ver)/Makefile \
|
||||
$(BUILDDIR)/$(MPC_VER)/Makefile \
|
||||
: $(MPC_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
@ -468,11 +499,11 @@ $(BUILDDIR)/$(mpc_ver)/Makefile \
|
||||
# Only valid if glibc target -> linux
|
||||
# proper destructor handling for c++
|
||||
ifneq (,$(findstring linux,$(TARGET)))
|
||||
$(BUILDDIR)/$(gcc_ver)/Makefile : CONFIG += --enable-__cxa_atexit
|
||||
$(BUILDDIR)/$(GCC_VER)/Makefile : CONFIG += --enable-__cxa_atexit
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH), armhfp)
|
||||
$(BUILDDIR)/$(gcc_ver)/Makefile : CONFIG += --with-float=hard
|
||||
$(BUILDDIR)/$(GCC_VER)/Makefile : CONFIG += --with-float=hard
|
||||
endif
|
||||
|
||||
ifneq ($(filter riscv64 ppc64le s390x, $(ARCH)), )
|
||||
@ -487,7 +518,7 @@ endif
|
||||
# skip native language.
|
||||
# and link and assemble with the binutils we created
|
||||
# earlier, so --with-gnu*
|
||||
$(BUILDDIR)/$(gcc_ver)/Makefile \
|
||||
$(BUILDDIR)/$(GCC_VER)/Makefile \
|
||||
: $(GCC_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
mkdir -p $(@D)
|
||||
@ -509,17 +540,17 @@ $(BUILDDIR)/$(gcc_ver)/Makefile \
|
||||
@echo 'done'
|
||||
|
||||
# need binutils for gcc
|
||||
$(gcc) : $(binutils)
|
||||
$(GCC) : $(BINUTILS)
|
||||
|
||||
# as of 4.3 or so need these for doing config
|
||||
$(BUILDDIR)/$(gcc_ver)/Makefile : $(gmp) $(mpfr) $(mpc)
|
||||
$(mpfr) : $(gmp)
|
||||
$(mpc) : $(gmp) $(mpfr)
|
||||
$(BUILDDIR)/$(GCC_VER)/Makefile : $(GMP) $(MPFR) $(MPC)
|
||||
$(MPFR) : $(GMP)
|
||||
$(MPC) : $(GMP) $(MPFR)
|
||||
|
||||
################################################################################
|
||||
# Build gdb but only where host and target match
|
||||
ifeq ($(HOST), $(TARGET))
|
||||
$(BUILDDIR)/$(gdb_ver)/Makefile: $(GDB_CFG)
|
||||
$(BUILDDIR)/$(GDB_VER)/Makefile: $(GDB_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
mkdir -p $(@D)
|
||||
( \
|
||||
@ -532,9 +563,9 @@ ifeq ($(HOST), $(TARGET))
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
$(gdb): $(gcc)
|
||||
$(GDB): $(GCC)
|
||||
else
|
||||
$(BUILDDIR)/$(gdb_ver)/Makefile:
|
||||
$(BUILDDIR)/$(GDB_VER)/Makefile:
|
||||
$(info Faking $@, not used when cross-compiling)
|
||||
mkdir -p $(@D)
|
||||
echo "install:" > $@
|
||||
@ -543,7 +574,7 @@ endif
|
||||
|
||||
################################################################################
|
||||
# very straightforward. just build a ccache. it is only for host.
|
||||
$(BUILDDIR)/$(ccache_ver)/Makefile \
|
||||
$(BUILDDIR)/$(CCACHE_VER)/Makefile \
|
||||
: $(CCACHE_SRC_MARKER)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
@ -554,12 +585,12 @@ $(BUILDDIR)/$(ccache_ver)/Makefile \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
gccpatch = $(TARGETDIR)/gcc-patched
|
||||
GCC_PATCHED = $(TARGETDIR)/gcc-patched
|
||||
|
||||
################################################################################
|
||||
# For some reason cpp is not created as a target-compiler
|
||||
ifeq ($(HOST),$(TARGET))
|
||||
$(gccpatch) : $(gcc) link_libs
|
||||
$(GCC_PATCHED) : $(GCC) link_libs
|
||||
@echo -n 'Creating compiler symlinks...'
|
||||
@for f in cpp; do \
|
||||
if [ ! -e $(PREFIX)/bin/$(TARGET)-$$f ]; \
|
||||
@ -587,7 +618,7 @@ ifeq ($(HOST),$(TARGET))
|
||||
done;)
|
||||
@echo 'done'
|
||||
else
|
||||
$(gccpatch) :
|
||||
$(GCC_PATCHED) :
|
||||
@echo 'done'
|
||||
endif
|
||||
|
||||
@ -615,7 +646,7 @@ $(PREFIX)/devkit.info:
|
||||
echo '# This file describes to configure how to interpret the contents of this' >> $@
|
||||
echo '# devkit' >> $@
|
||||
echo '' >> $@
|
||||
echo 'DEVKIT_NAME="$(gcc_ver) - $(LINUX_VERSION)"' >> $@
|
||||
echo 'DEVKIT_NAME="$(GCC_VER) - $(LINUX_VERSION)"' >> $@
|
||||
echo 'DEVKIT_TOOLCHAIN_PATH="$$DEVKIT_ROOT/bin"' >> $@
|
||||
echo 'DEVKIT_SYSROOT="$$DEVKIT_ROOT/$(TARGET)/sysroot"' >> $@
|
||||
echo 'DEVKIT_EXTRA_PATH="$$DEVKIT_ROOT/bin"' >> $@
|
||||
@ -651,32 +682,32 @@ ifeq ($(TARGET), $(HOST))
|
||||
@echo 'Creating missing $* soft link'
|
||||
ln -s $(TARGET)-$* $@
|
||||
|
||||
missing-links := $(addprefix $(PREFIX)/bin/, \
|
||||
addr2line ar as c++ c++filt dwp elfedit g++ gcc gcc-$(gcc_ver_only) gprof ld ld.bfd \
|
||||
MISSING_LINKS := $(addprefix $(PREFIX)/bin/, \
|
||||
addr2line ar as c++ c++filt dwp elfedit g++ gcc gcc-$(GCC_VER_ONLY) gprof ld ld.bfd \
|
||||
ld.gold nm objcopy objdump ranlib readelf size strings strip)
|
||||
endif
|
||||
|
||||
# Add link to work around "plugin needed to handle lto object" (JDK-8344272)
|
||||
$(PREFIX)/lib/bfd-plugins/liblto_plugin.so: $(PREFIX)/libexec/gcc/$(TARGET)/$(gcc_ver_only)/liblto_plugin.so
|
||||
$(PREFIX)/lib/bfd-plugins/liblto_plugin.so: $(PREFIX)/libexec/gcc/$(TARGET)/$(GCC_VER_ONLY)/liblto_plugin.so
|
||||
@echo 'Creating missing $(@F) soft link'
|
||||
@mkdir -p $(@D)
|
||||
ln -s $$(realpath -s --relative-to=$(@D) $<) $@
|
||||
|
||||
missing-links += $(PREFIX)/lib/bfd-plugins/liblto_plugin.so
|
||||
MISSING_LINKS += $(PREFIX)/lib/bfd-plugins/liblto_plugin.so
|
||||
|
||||
################################################################################
|
||||
|
||||
bfdlib : $(bfdlib)
|
||||
binutils : $(binutils)
|
||||
rpms : $(rpms)
|
||||
libs : $(libs)
|
||||
bfdlib : $(BFDLIB)
|
||||
binutils : $(BINUTILS)
|
||||
rpms : $(RPMS)
|
||||
libs : $(LIBS)
|
||||
sysroot : rpms libs
|
||||
gcc : sysroot $(gcc) $(gccpatch)
|
||||
gdb : $(gdb)
|
||||
all : binutils gcc bfdlib $(PREFIX)/devkit.info $(missing-links) $(SYSROOT_LINKS) \
|
||||
gcc : sysroot $(GCC) $(GCC_PATCHED)
|
||||
gdb : $(GDB)
|
||||
all : binutils gcc bfdlib $(PREFIX)/devkit.info $(MISSING_LINKS) $(SYSROOT_LINKS) \
|
||||
$(THESE_MAKEFILES) gdb
|
||||
|
||||
# this is only built for host. so separate.
|
||||
ccache : $(ccache)
|
||||
ccache : $(CCACHE)
|
||||
|
||||
.PHONY : gcc all binutils bfdlib link_libs rpms libs sysroot
|
||||
|
||||
@ -93,7 +93,7 @@ elif test "x$TARGET_PLATFORM" = xlinux_x64; then
|
||||
rpm2cpio $OUTPUT_ROOT/m4-$M4_VERSION.el6.x86_64.rpm | cpio -d -i
|
||||
elif test "x$TARGET_PLATFORM" = xlinux_x86; then
|
||||
M4_VERSION=1.4.13-5
|
||||
wget http://yum.oracle.com/repo/OracleLinux/OL6/latest/i386/getPackage/m4-$M4_VERSION.el6.i686.rpm
|
||||
wget https://yum.oracle.com/repo/OracleLinux/OL6/latest/i386/getPackage/m4-$M4_VERSION.el6.i686.rpm
|
||||
cd $IMAGE_DIR
|
||||
rpm2cpio $OUTPUT_ROOT/m4-$M4_VERSION.el6.i686.rpm | cpio -d -i
|
||||
else
|
||||
|
||||
@ -152,7 +152,7 @@ $(eval $(call SetupJdkExecutable, BUILD_GTEST_LAUNCHER, \
|
||||
-I$(GTEST_FRAMEWORK_SRC)/googlemock \
|
||||
-I$(GTEST_FRAMEWORK_SRC)/googlemock/include, \
|
||||
LD_SET_ORIGIN := false, \
|
||||
LDFLAGS_unix := $(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LDFLAGS_unix := $(call SetSharedLibraryOrigin), \
|
||||
JDK_LIBS := gtest:libjvm, \
|
||||
COPY_DEBUG_SYMBOLS := $(GTEST_COPY_DEBUG_SYMBOLS), \
|
||||
ZIP_EXTERNAL_DEBUG_SYMBOLS := false, \
|
||||
|
||||
@ -158,6 +158,10 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
WIN_EXPORT_FILE := $(JVM_OUTPUTDIR)/win-exports.def
|
||||
endif
|
||||
|
||||
ifeq ($(SHIP_DEBUG_SYMBOLS), public)
|
||||
CFLAGS_STRIPPED_DEBUGINFO := -DHAS_STRIPPED_DEBUGINFO
|
||||
endif
|
||||
|
||||
JVM_LDFLAGS += -def:$(WIN_EXPORT_FILE)
|
||||
endif
|
||||
|
||||
@ -183,13 +187,13 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJVM, \
|
||||
CFLAGS := $(JVM_CFLAGS), \
|
||||
abstract_vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
|
||||
arguments.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
|
||||
whitebox.cpp_CXXFLAGS := $(CFLAGS_STRIPPED_DEBUGINFO), \
|
||||
DISABLED_WARNINGS_gcc := $(DISABLED_WARNINGS_gcc), \
|
||||
DISABLED_WARNINGS_gcc_ad_$(HOTSPOT_TARGET_CPU_ARCH).cpp := nonnull, \
|
||||
DISABLED_WARNINGS_gcc_bytecodeInterpreter.cpp := unused-label, \
|
||||
DISABLED_WARNINGS_gcc_c1_Runtime1_aarch64.cpp := unused-const-variable, \
|
||||
DISABLED_WARNINGS_gcc_cgroupV1Subsystem_linux.cpp := address, \
|
||||
DISABLED_WARNINGS_gcc_cgroupV2Subsystem_linux.cpp := address, \
|
||||
DISABLED_WARNINGS_gcc_g1FreeIdSet.cpp := unused-const-variable, \
|
||||
DISABLED_WARNINGS_gcc_handshake.cpp := stringop-overflow, \
|
||||
DISABLED_WARNINGS_gcc_interp_masm_x86.cpp := uninitialized, \
|
||||
DISABLED_WARNINGS_gcc_javaClasses.cpp := unused-const-variable, \
|
||||
|
||||
@ -57,7 +57,7 @@ ifeq ($(call check-jvm-feature, zero), true)
|
||||
-DZERO_LIBARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' $(LIBFFI_CFLAGS)
|
||||
JVM_LIBS_FEATURES += $(LIBFFI_LIBS)
|
||||
ifeq ($(ENABLE_LIBFFI_BUNDLING), true)
|
||||
JVM_LDFLAGS_FEATURES += $(call SET_EXECUTABLE_ORIGIN,/..)
|
||||
JVM_LDFLAGS_FEATURES += $(call SetExecutableOrigin,/..)
|
||||
endif
|
||||
else
|
||||
JVM_EXCLUDE_PATTERNS += /zero/
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
// Java extension
|
||||
"jdk.project.jdkhome": "{{OUTPUTDIR}}/jdk",
|
||||
"jdk.java.onSave.organizeImports": false, // prevents unnecessary changes
|
||||
"jdk.serverVmOptions": ["-Xmx2G"], // prevent out of memory
|
||||
|
||||
// Additional conventions
|
||||
"files.associations": {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2025, 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
|
||||
@ -61,7 +61,7 @@ public class CompilerThreadPool {
|
||||
} catch (InterruptedException ie) {
|
||||
// (Re-)Cancel if current thread also interrupted
|
||||
pool.shutdownNow();
|
||||
// Preserve interrupt status
|
||||
// Preserve interrupted status
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +33,6 @@ include gensrc/GensrcBuffer.gmk
|
||||
include gensrc/GensrcCharacterData.gmk
|
||||
include gensrc/GensrcCharsetCoder.gmk
|
||||
include gensrc/GensrcCharsetMapping.gmk
|
||||
include gensrc/GensrcExceptions.gmk
|
||||
include gensrc/GensrcMisc.gmk
|
||||
include gensrc/GensrcModuleLoaderMap.gmk
|
||||
include gensrc/GensrcRegex.gmk
|
||||
|
||||
@ -154,6 +154,8 @@ endif
|
||||
|
||||
################################################################################
|
||||
## Build libsyslookup
|
||||
## The LIBDL dependency on Linux is needed to dynamically access libdl symbols,
|
||||
## which may be needed as part of resolving some standard symbols
|
||||
################################################################################
|
||||
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIBSYSLOOKUP, \
|
||||
@ -196,7 +198,7 @@ ifeq ($(call isTargetOs, linux)+$(call isTargetCpu, x86_64)+$(INCLUDE_COMPILER2)
|
||||
OPTIMIZATION := HIGH, \
|
||||
CXXFLAGS := -std=c++17, \
|
||||
DISABLED_WARNINGS_gcc := unused-variable, \
|
||||
LIBS_linux := $(LIBDL) $(LIBM), \
|
||||
LIBS_linux := $(LIBM), \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIBSIMD_SORT)
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
include MakeIncludeStart.gmk
|
||||
ifeq ($(INCLUDE), true)
|
||||
|
||||
################################################################################
|
||||
|
||||
GENSRC_EXCEPTIONS :=
|
||||
|
||||
GENSRC_EXCEPTIONS_DST := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/java/nio
|
||||
|
||||
GENSRC_EXCEPTIONS_SRC := $(MODULE_SRC)/share/classes/java/nio
|
||||
GENSRC_EXCEPTIONS_CMD := $(TOPDIR)/make/scripts/genExceptions.sh
|
||||
|
||||
GENSRC_EXCEPTIONS_SRC_DIRS := . charset channels
|
||||
|
||||
$(GENSRC_EXCEPTIONS_DST)/_the.%.marker: $(GENSRC_EXCEPTIONS_SRC)/%/exceptions \
|
||||
$(GENSRC_EXCEPTIONS_CMD)
|
||||
$(call LogInfo, Generating exceptions java.nio $*)
|
||||
$(call MakeDir, $(@D)/$*)
|
||||
SCRIPTS="$(TOPDIR)/make/scripts" AWK="$(AWK)" SH="$(SH)" $(SH) \
|
||||
$(GENSRC_EXCEPTIONS_CMD) $< $(@D)/$* $(LOG_DEBUG)
|
||||
$(TOUCH) $@
|
||||
|
||||
GENSRC_EXCEPTIONS += $(foreach D, $(GENSRC_EXCEPTIONS_SRC_DIRS), $(GENSRC_EXCEPTIONS_DST)/_the.$(D).marker)
|
||||
|
||||
$(GENSRC_EXCEPTIONS): $(BUILD_TOOLS_JDK)
|
||||
|
||||
TARGETS += $(GENSRC_EXCEPTIONS)
|
||||
|
||||
################################################################################
|
||||
|
||||
endif # include guard
|
||||
include MakeIncludeEnd.gmk
|
||||
@ -51,7 +51,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBMLIB_IMAGE, \
|
||||
$(LIBMLIB_IMAGE_CFLAGS), \
|
||||
DISABLED_WARNINGS_gcc := unused-function, \
|
||||
DISABLED_WARNINGS_clang_mlib_ImageCreate.c := unused-function, \
|
||||
LIBS_unix := $(LIBDL) $(LIBM), \
|
||||
LIBS_unix := $(LIBM), \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIBMLIB_IMAGE)
|
||||
@ -264,7 +264,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
|
||||
JDK_LIBS_macosx := libosxapp, \
|
||||
LIBS := $(GIFLIB_LIBS) $(LIBJPEG_LIBS) $(LIBZ_LIBS) $(PNG_LIBS) $(ICONV_LIBS), \
|
||||
LIBS_unix := $(LIBM) $(LIBPTHREAD), \
|
||||
LIBS_linux := $(LIBDL) $(X_LIBS) -lX11 -lXext, \
|
||||
LIBS_linux := $(X_LIBS) -lX11 -lXext, \
|
||||
LIBS_macosx := \
|
||||
-framework ApplicationServices \
|
||||
-framework Cocoa \
|
||||
|
||||
@ -43,8 +43,6 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBINSTRUMENT, \
|
||||
JDK_LIBS := java.base:libjava java.base:libjli java.base:libjvm, \
|
||||
LIBS := $(ICONV_LIBS), \
|
||||
LIBS_unix := $(LIBZ_LIBS), \
|
||||
LIBS_linux := $(LIBDL), \
|
||||
LIBS_aix := $(LIBDL), \
|
||||
LIBS_macosx := \
|
||||
-framework ApplicationServices \
|
||||
-framework Cocoa \
|
||||
|
||||
@ -27,7 +27,5 @@
|
||||
|
||||
DOCLINT += -Xdoclint:all/protected \
|
||||
'-Xdoclint/package:java.*,javax.*'
|
||||
COPY += .js
|
||||
CLEAN += .properties
|
||||
|
||||
################################################################################
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
################################################################################
|
||||
|
||||
include LauncherCommon.gmk
|
||||
|
||||
################################################################################
|
||||
## Build jrunscript
|
||||
################################################################################
|
||||
|
||||
$(eval $(call SetupBuildLauncher, jrunscript, \
|
||||
MAIN_CLASS := com.sun.tools.script.shell.Main, \
|
||||
JAVA_ARGS := --add-modules ALL-DEFAULT, \
|
||||
))
|
||||
|
||||
################################################################################
|
||||
@ -41,7 +41,7 @@ ifeq ($(call isTargetOs, linux), true)
|
||||
java.base:libnio \
|
||||
java.base:libnio/ch, \
|
||||
JDK_LIBS := java.base:libjava java.base:libnet, \
|
||||
LIBS_linux := $(LIBDL) $(LIBPTHREAD), \
|
||||
LIBS_linux := $(LIBDL), \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIBSCTP)
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2007, 2020, 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.
|
||||
#
|
||||
|
||||
# Parse the first contiguous comment block in this script and generate
|
||||
# a java comment block. If this script is invoked with a copyright
|
||||
# year/year range, the java comment block will contain a Sun copyright.
|
||||
|
||||
COPYRIGHT_YEARS="$1"
|
||||
|
||||
cat <<__END__
|
||||
/*
|
||||
__END__
|
||||
|
||||
if [ "x$COPYRIGHT_YEARS" != x ]; then
|
||||
cat <<__END__
|
||||
* Copyright (c) $COPYRIGHT_YEARS Oracle and/or its affiliates. All rights reserved.
|
||||
__END__
|
||||
fi
|
||||
|
||||
$AWK ' /^#.*Copyright.*Oracle/ { next }
|
||||
/^#([^!]|$)/ { sub(/^#/, " *"); print }
|
||||
/^$/ { print " */"; exit } ' $0
|
||||
@ -1,116 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright (c) 2000, 2025, 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.
|
||||
#
|
||||
|
||||
# Generate exception classes
|
||||
|
||||
SPEC=$1
|
||||
DST=$2
|
||||
|
||||
gen() {
|
||||
ID=$1
|
||||
WHAT=$2
|
||||
SVUID=$3
|
||||
ARG_TYPE=$4
|
||||
ARG_ID=$5
|
||||
ARG_PROP=$6
|
||||
ARG_PHRASE=$7
|
||||
ARG_PARAM="$ARG_TYPE$ $ARG_ID"
|
||||
echo '-->' $DST/$ID.java
|
||||
out=$DST/${ID}.java
|
||||
|
||||
$SH ${SCRIPTS}/addNotices.sh "$COPYRIGHT_YEARS" > $out
|
||||
|
||||
cat >>$out <<__END__
|
||||
|
||||
// -- This file was mechanically generated: Do not edit! -- //
|
||||
|
||||
package $PACKAGE;
|
||||
|
||||
|
||||
/**$WHAT
|
||||
*
|
||||
* @since $SINCE
|
||||
*/
|
||||
|
||||
public `if [ ${ABSTRACT:-0} = 1 ];
|
||||
then echo 'abstract '; fi`class $ID
|
||||
extends ${SUPER}
|
||||
{
|
||||
|
||||
@java.io.Serial
|
||||
private static final long serialVersionUID = $SVUID;
|
||||
__END__
|
||||
|
||||
if [ $ARG_ID ]; then
|
||||
|
||||
cat >>$out <<__END__
|
||||
|
||||
/**
|
||||
* The $ARG_PHRASE.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private $ARG_TYPE $ARG_ID;
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class.
|
||||
*
|
||||
* @param $ARG_ID
|
||||
* The $ARG_PHRASE
|
||||
*/
|
||||
public $ID($ARG_TYPE $ARG_ID) {
|
||||
super(String.valueOf($ARG_ID));
|
||||
this.$ARG_ID = $ARG_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the $ARG_PHRASE.
|
||||
*
|
||||
* @return The $ARG_PHRASE
|
||||
*/
|
||||
public $ARG_TYPE get$ARG_PROP() {
|
||||
return $ARG_ID;
|
||||
}
|
||||
|
||||
}
|
||||
__END__
|
||||
|
||||
else
|
||||
|
||||
cat >>$out <<__END__
|
||||
|
||||
/**
|
||||
* Constructs an instance of this class.
|
||||
*/
|
||||
public $ID() { }
|
||||
|
||||
}
|
||||
__END__
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
. $SPEC
|
||||
@ -1266,39 +1266,39 @@ source %{
|
||||
// adlc register classes to make AArch64 rheapbase (r27) and rfp (r29)
|
||||
// registers conditionally reserved.
|
||||
|
||||
_ANY_REG32_mask = _ALL_REG32_mask;
|
||||
_ANY_REG32_mask.Remove(OptoReg::as_OptoReg(r31_sp->as_VMReg()));
|
||||
_ANY_REG32_mask.assignFrom(_ALL_REG32_mask);
|
||||
_ANY_REG32_mask.remove(OptoReg::as_OptoReg(r31_sp->as_VMReg()));
|
||||
|
||||
_ANY_REG_mask = _ALL_REG_mask;
|
||||
_ANY_REG_mask.assignFrom(_ALL_REG_mask);
|
||||
|
||||
_PTR_REG_mask = _ALL_REG_mask;
|
||||
_PTR_REG_mask.assignFrom(_ALL_REG_mask);
|
||||
|
||||
_NO_SPECIAL_REG32_mask = _ALL_REG32_mask;
|
||||
_NO_SPECIAL_REG32_mask.SUBTRACT(_NON_ALLOCATABLE_REG32_mask);
|
||||
_NO_SPECIAL_REG32_mask.assignFrom(_ALL_REG32_mask);
|
||||
_NO_SPECIAL_REG32_mask.subtract(_NON_ALLOCATABLE_REG32_mask);
|
||||
|
||||
_NO_SPECIAL_REG_mask = _ALL_REG_mask;
|
||||
_NO_SPECIAL_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask);
|
||||
_NO_SPECIAL_REG_mask.assignFrom(_ALL_REG_mask);
|
||||
_NO_SPECIAL_REG_mask.subtract(_NON_ALLOCATABLE_REG_mask);
|
||||
|
||||
_NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask;
|
||||
_NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask);
|
||||
_NO_SPECIAL_PTR_REG_mask.assignFrom(_ALL_REG_mask);
|
||||
_NO_SPECIAL_PTR_REG_mask.subtract(_NON_ALLOCATABLE_REG_mask);
|
||||
|
||||
// r27 is not allocatable when compressed oops is on and heapbase is not
|
||||
// zero, compressed klass pointers doesn't use r27 after JDK-8234794
|
||||
if (UseCompressedOops && (CompressedOops::base() != nullptr)) {
|
||||
_NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg()));
|
||||
_NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg()));
|
||||
_NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg()));
|
||||
_NO_SPECIAL_REG32_mask.remove(OptoReg::as_OptoReg(r27->as_VMReg()));
|
||||
_NO_SPECIAL_REG_mask.remove(OptoReg::as_OptoReg(r27->as_VMReg()));
|
||||
_NO_SPECIAL_PTR_REG_mask.remove(OptoReg::as_OptoReg(r27->as_VMReg()));
|
||||
}
|
||||
|
||||
// r29 is not allocatable when PreserveFramePointer is on
|
||||
if (PreserveFramePointer) {
|
||||
_NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
|
||||
_NO_SPECIAL_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
|
||||
_NO_SPECIAL_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
|
||||
_NO_SPECIAL_REG32_mask.remove(OptoReg::as_OptoReg(r29->as_VMReg()));
|
||||
_NO_SPECIAL_REG_mask.remove(OptoReg::as_OptoReg(r29->as_VMReg()));
|
||||
_NO_SPECIAL_PTR_REG_mask.remove(OptoReg::as_OptoReg(r29->as_VMReg()));
|
||||
}
|
||||
|
||||
_NO_SPECIAL_NO_RFP_PTR_REG_mask = _NO_SPECIAL_PTR_REG_mask;
|
||||
_NO_SPECIAL_NO_RFP_PTR_REG_mask.Remove(OptoReg::as_OptoReg(r29->as_VMReg()));
|
||||
_NO_SPECIAL_NO_RFP_PTR_REG_mask.assignFrom(_NO_SPECIAL_PTR_REG_mask);
|
||||
_NO_SPECIAL_NO_RFP_PTR_REG_mask.remove(OptoReg::as_OptoReg(r29->as_VMReg()));
|
||||
}
|
||||
|
||||
// Optimizaton of volatile gets and puts
|
||||
@ -1734,7 +1734,7 @@ uint MachBreakpointNode::size(PhaseRegAlloc *ra_) const {
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
|
||||
const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::EMPTY;
|
||||
|
||||
int ConstantTable::calculate_table_base_offset() const {
|
||||
return 0; // absolute addressing, no offset
|
||||
@ -2520,10 +2520,10 @@ uint Matcher::int_pressure_limit()
|
||||
// as a spilled LRG. Spilling heuristics(Spill-USE) explicitly skip
|
||||
// derived pointers and lastly fail to spill after reaching maximum
|
||||
// number of iterations. Lowering the default pressure threshold to
|
||||
// (_NO_SPECIAL_REG32_mask.Size() minus 1) forces CallNode to become
|
||||
// (_NO_SPECIAL_REG32_mask.size() minus 1) forces CallNode to become
|
||||
// a high register pressure area of the code so that split_DEF can
|
||||
// generate DefinitionSpillCopy for the derived pointer.
|
||||
uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.Size() - 1;
|
||||
uint default_int_pressure_threshold = _NO_SPECIAL_REG32_mask.size() - 1;
|
||||
if (!PreserveFramePointer) {
|
||||
// When PreserveFramePointer is off, frame pointer is allocatable,
|
||||
// but different from other SOC registers, it is excluded from
|
||||
@ -2538,38 +2538,34 @@ uint Matcher::int_pressure_limit()
|
||||
uint Matcher::float_pressure_limit()
|
||||
{
|
||||
// _FLOAT_REG_mask is generated by adlc from the float_reg register class.
|
||||
return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.Size() : FLOATPRESSURE;
|
||||
return (FLOATPRESSURE == -1) ? _FLOAT_REG_mask.size() : FLOATPRESSURE;
|
||||
}
|
||||
|
||||
bool Matcher::use_asm_for_ldiv_by_con(jlong divisor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RegMask Matcher::divI_proj_mask() {
|
||||
const RegMask& Matcher::divI_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask();
|
||||
return RegMask::EMPTY;
|
||||
}
|
||||
|
||||
// Register for MODI projection of divmodI.
|
||||
RegMask Matcher::modI_proj_mask() {
|
||||
const RegMask& Matcher::modI_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask();
|
||||
return RegMask::EMPTY;
|
||||
}
|
||||
|
||||
// Register for DIVL projection of divmodL.
|
||||
RegMask Matcher::divL_proj_mask() {
|
||||
const RegMask& Matcher::divL_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask();
|
||||
return RegMask::EMPTY;
|
||||
}
|
||||
|
||||
// Register for MODL projection of divmodL.
|
||||
RegMask Matcher::modL_proj_mask() {
|
||||
const RegMask& Matcher::modL_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask();
|
||||
}
|
||||
|
||||
const RegMask Matcher::method_handle_invoke_SP_save_mask() {
|
||||
return FP_REG_mask();
|
||||
return RegMask::EMPTY;
|
||||
}
|
||||
|
||||
bool size_fits_all_mem_uses(AddPNode* addp, int shift) {
|
||||
|
||||
@ -215,11 +215,6 @@ source %{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Op_ExpandV:
|
||||
if (UseSVE < 2 || is_subword_type(bt)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Op_VectorMaskToLong:
|
||||
if (UseSVE > 0 && vlen > 64) {
|
||||
return false;
|
||||
@ -7183,37 +7178,68 @@ instruct vcompress(vReg dst, vReg src, pRegGov pg) %{
|
||||
%}
|
||||
|
||||
instruct vcompressB(vReg dst, vReg src, pReg pg, vReg tmp1, vReg tmp2,
|
||||
vReg tmp3, vReg tmp4, pReg ptmp, pRegGov pgtmp) %{
|
||||
vReg tmp3, pReg ptmp, pRegGov pgtmp) %{
|
||||
predicate(UseSVE > 0 && Matcher::vector_element_basic_type(n) == T_BYTE);
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ptmp, TEMP pgtmp);
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP ptmp, TEMP pgtmp);
|
||||
match(Set dst (CompressV src pg));
|
||||
format %{ "vcompressB $dst, $src, $pg\t# KILL $tmp1, $tmp2, $tmp3, tmp4, $ptmp, $pgtmp" %}
|
||||
format %{ "vcompressB $dst, $src, $pg\t# KILL $tmp1, $tmp2, $tmp3, $ptmp, $pgtmp" %}
|
||||
ins_encode %{
|
||||
uint length_in_bytes = Matcher::vector_length_in_bytes(this);
|
||||
__ sve_compress_byte($dst$$FloatRegister, $src$$FloatRegister, $pg$$PRegister,
|
||||
$tmp1$$FloatRegister,$tmp2$$FloatRegister,
|
||||
$tmp3$$FloatRegister,$tmp4$$FloatRegister,
|
||||
$ptmp$$PRegister, $pgtmp$$PRegister);
|
||||
$tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister,
|
||||
$ptmp$$PRegister, $pgtmp$$PRegister, length_in_bytes);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vcompressS(vReg dst, vReg src, pReg pg,
|
||||
vReg tmp1, vReg tmp2, pRegGov pgtmp) %{
|
||||
instruct vcompressS(vReg dst, vReg src, pReg pg, vReg tmp1, vReg tmp2, pRegGov pgtmp) %{
|
||||
predicate(UseSVE > 0 && Matcher::vector_element_basic_type(n) == T_SHORT);
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP pgtmp);
|
||||
match(Set dst (CompressV src pg));
|
||||
format %{ "vcompressS $dst, $src, $pg\t# KILL $tmp1, $tmp2, $pgtmp" %}
|
||||
ins_encode %{
|
||||
uint length_in_bytes = Matcher::vector_length_in_bytes(this);
|
||||
__ sve_dup($tmp1$$FloatRegister, __ H, 0);
|
||||
__ sve_compress_short($dst$$FloatRegister, $src$$FloatRegister, $pg$$PRegister,
|
||||
$tmp1$$FloatRegister,$tmp2$$FloatRegister, $pgtmp$$PRegister);
|
||||
$tmp1$$FloatRegister, $tmp2$$FloatRegister, $pgtmp$$PRegister,
|
||||
length_in_bytes);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vexpand(vReg dst, vReg src, pRegGov pg) %{
|
||||
instruct vexpand_neon(vReg dst, vReg src, vReg mask, vReg tmp1, vReg tmp2) %{
|
||||
predicate(UseSVE == 0);
|
||||
match(Set dst (ExpandV src mask));
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
|
||||
format %{ "vexpand_neon $dst, $src, $mask\t# KILL $tmp1, $tmp2" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
int length_in_bytes = (int) Matcher::vector_length_in_bytes(this);
|
||||
__ vector_expand_neon($dst$$FloatRegister, $src$$FloatRegister, $mask$$FloatRegister,
|
||||
$tmp1$$FloatRegister, $tmp2$$FloatRegister, bt, length_in_bytes);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vexpand_sve(vReg dst, vReg src, pRegGov pg, vReg tmp1, vReg tmp2) %{
|
||||
predicate(UseSVE == 1 || (UseSVE == 2 && type2aelembytes(Matcher::vector_element_basic_type(n)) < 4));
|
||||
match(Set dst (ExpandV src pg));
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
|
||||
format %{ "vexpand_sve $dst, $src, $pg\t# KILL $tmp1, $tmp2" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
int length_in_bytes = (int) Matcher::vector_length_in_bytes(this);
|
||||
__ vector_expand_sve($dst$$FloatRegister, $src$$FloatRegister, $pg$$PRegister,
|
||||
$tmp1$$FloatRegister, $tmp2$$FloatRegister, bt, length_in_bytes);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vexpand_sve2_SD(vReg dst, vReg src, pRegGov pg) %{
|
||||
predicate(UseSVE == 2 && type2aelembytes(Matcher::vector_element_basic_type(n)) >= 4);
|
||||
match(Set dst (ExpandV src pg));
|
||||
effect(TEMP_DEF dst);
|
||||
format %{ "vexpand $dst, $pg, $src" %}
|
||||
format %{ "vexpand_sve2_SD $dst, $src, $pg" %}
|
||||
ins_encode %{
|
||||
// Example input: src = 1 2 3 4 5 6 7 8
|
||||
// pg = 1 0 0 1 1 0 1 1
|
||||
@ -7224,7 +7250,6 @@ instruct vexpand(vReg dst, vReg src, pRegGov pg) %{
|
||||
// for TBL whose value is used to select the indexed element from src vector.
|
||||
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(UseSVE == 2 && !is_subword_type(bt), "unsupported");
|
||||
Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt);
|
||||
// dst = 0 0 0 0 0 0 0 0
|
||||
__ sve_dup($dst$$FloatRegister, size, 0);
|
||||
|
||||
@ -205,11 +205,6 @@ source %{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Op_ExpandV:
|
||||
if (UseSVE < 2 || is_subword_type(bt)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case Op_VectorMaskToLong:
|
||||
if (UseSVE > 0 && vlen > 64) {
|
||||
return false;
|
||||
@ -5129,37 +5124,68 @@ instruct vcompress(vReg dst, vReg src, pRegGov pg) %{
|
||||
%}
|
||||
|
||||
instruct vcompressB(vReg dst, vReg src, pReg pg, vReg tmp1, vReg tmp2,
|
||||
vReg tmp3, vReg tmp4, pReg ptmp, pRegGov pgtmp) %{
|
||||
vReg tmp3, pReg ptmp, pRegGov pgtmp) %{
|
||||
predicate(UseSVE > 0 && Matcher::vector_element_basic_type(n) == T_BYTE);
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ptmp, TEMP pgtmp);
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP ptmp, TEMP pgtmp);
|
||||
match(Set dst (CompressV src pg));
|
||||
format %{ "vcompressB $dst, $src, $pg\t# KILL $tmp1, $tmp2, $tmp3, tmp4, $ptmp, $pgtmp" %}
|
||||
format %{ "vcompressB $dst, $src, $pg\t# KILL $tmp1, $tmp2, $tmp3, $ptmp, $pgtmp" %}
|
||||
ins_encode %{
|
||||
uint length_in_bytes = Matcher::vector_length_in_bytes(this);
|
||||
__ sve_compress_byte($dst$$FloatRegister, $src$$FloatRegister, $pg$$PRegister,
|
||||
$tmp1$$FloatRegister,$tmp2$$FloatRegister,
|
||||
$tmp3$$FloatRegister,$tmp4$$FloatRegister,
|
||||
$ptmp$$PRegister, $pgtmp$$PRegister);
|
||||
$tmp1$$FloatRegister, $tmp2$$FloatRegister, $tmp3$$FloatRegister,
|
||||
$ptmp$$PRegister, $pgtmp$$PRegister, length_in_bytes);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vcompressS(vReg dst, vReg src, pReg pg,
|
||||
vReg tmp1, vReg tmp2, pRegGov pgtmp) %{
|
||||
instruct vcompressS(vReg dst, vReg src, pReg pg, vReg tmp1, vReg tmp2, pRegGov pgtmp) %{
|
||||
predicate(UseSVE > 0 && Matcher::vector_element_basic_type(n) == T_SHORT);
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2, TEMP pgtmp);
|
||||
match(Set dst (CompressV src pg));
|
||||
format %{ "vcompressS $dst, $src, $pg\t# KILL $tmp1, $tmp2, $pgtmp" %}
|
||||
ins_encode %{
|
||||
uint length_in_bytes = Matcher::vector_length_in_bytes(this);
|
||||
__ sve_dup($tmp1$$FloatRegister, __ H, 0);
|
||||
__ sve_compress_short($dst$$FloatRegister, $src$$FloatRegister, $pg$$PRegister,
|
||||
$tmp1$$FloatRegister,$tmp2$$FloatRegister, $pgtmp$$PRegister);
|
||||
$tmp1$$FloatRegister, $tmp2$$FloatRegister, $pgtmp$$PRegister,
|
||||
length_in_bytes);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vexpand(vReg dst, vReg src, pRegGov pg) %{
|
||||
instruct vexpand_neon(vReg dst, vReg src, vReg mask, vReg tmp1, vReg tmp2) %{
|
||||
predicate(UseSVE == 0);
|
||||
match(Set dst (ExpandV src mask));
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
|
||||
format %{ "vexpand_neon $dst, $src, $mask\t# KILL $tmp1, $tmp2" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
int length_in_bytes = (int) Matcher::vector_length_in_bytes(this);
|
||||
__ vector_expand_neon($dst$$FloatRegister, $src$$FloatRegister, $mask$$FloatRegister,
|
||||
$tmp1$$FloatRegister, $tmp2$$FloatRegister, bt, length_in_bytes);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vexpand_sve(vReg dst, vReg src, pRegGov pg, vReg tmp1, vReg tmp2) %{
|
||||
predicate(UseSVE == 1 || (UseSVE == 2 && type2aelembytes(Matcher::vector_element_basic_type(n)) < 4));
|
||||
match(Set dst (ExpandV src pg));
|
||||
effect(TEMP_DEF dst, TEMP tmp1, TEMP tmp2);
|
||||
format %{ "vexpand_sve $dst, $src, $pg\t# KILL $tmp1, $tmp2" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
int length_in_bytes = (int) Matcher::vector_length_in_bytes(this);
|
||||
__ vector_expand_sve($dst$$FloatRegister, $src$$FloatRegister, $pg$$PRegister,
|
||||
$tmp1$$FloatRegister, $tmp2$$FloatRegister, bt, length_in_bytes);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct vexpand_sve2_SD(vReg dst, vReg src, pRegGov pg) %{
|
||||
predicate(UseSVE == 2 && type2aelembytes(Matcher::vector_element_basic_type(n)) >= 4);
|
||||
match(Set dst (ExpandV src pg));
|
||||
effect(TEMP_DEF dst);
|
||||
format %{ "vexpand $dst, $pg, $src" %}
|
||||
format %{ "vexpand_sve2_SD $dst, $src, $pg" %}
|
||||
ins_encode %{
|
||||
// Example input: src = 1 2 3 4 5 6 7 8
|
||||
// pg = 1 0 0 1 1 0 1 1
|
||||
@ -5170,7 +5196,6 @@ instruct vexpand(vReg dst, vReg src, pRegGov pg) %{
|
||||
// for TBL whose value is used to select the indexed element from src vector.
|
||||
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
assert(UseSVE == 2 && !is_subword_type(bt), "unsupported");
|
||||
Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt);
|
||||
// dst = 0 0 0 0 0 0 0 0
|
||||
__ sve_dup($dst$$FloatRegister, size, 0);
|
||||
|
||||
@ -3486,6 +3486,7 @@ public:
|
||||
INSN(sve_smaxv, 0b00000100, 0b001000001); // signed maximum reduction to scalar
|
||||
INSN(sve_smin, 0b00000100, 0b001010000); // signed minimum vectors
|
||||
INSN(sve_sminv, 0b00000100, 0b001010001); // signed minimum reduction to scalar
|
||||
INSN(sve_splice,0b00000101, 0b101100100); // splice two vectors under predicate control, destructive
|
||||
INSN(sve_sub, 0b00000100, 0b000001000); // vector sub
|
||||
INSN(sve_uaddv, 0b00000100, 0b000001001); // unsigned add reduction to scalar
|
||||
INSN(sve_umax, 0b00000100, 0b001001000); // unsigned maximum vectors
|
||||
@ -4072,6 +4073,13 @@ public:
|
||||
INSN(sve_brkb, 0b10); // Break before first true condition
|
||||
#undef INSN
|
||||
|
||||
// SVE move prefix (unpredicated)
|
||||
void sve_movprfx(FloatRegister Zd, FloatRegister Zn) {
|
||||
starti;
|
||||
f(0b00000100, 31, 24), f(0b00, 23, 22), f(0b1, 21), f(0b00000, 20, 16);
|
||||
f(0b101111, 15, 10), rf(Zn, 5), rf(Zd, 0);
|
||||
}
|
||||
|
||||
// Element count and increment scalar (SVE)
|
||||
#define INSN(NAME, TYPE) \
|
||||
void NAME(Register Xdn, unsigned imm4 = 1, int pattern = 0b11111) { \
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
#ifndef CPU_AARCH64_ASSEMBLER_AARCH64_INLINE_HPP
|
||||
#define CPU_AARCH64_ASSEMBLER_AARCH64_INLINE_HPP
|
||||
|
||||
#include "asm/assembler.inline.hpp"
|
||||
#include "asm/assembler.hpp"
|
||||
#include "asm/codeBuffer.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
|
||||
|
||||
@ -216,10 +216,10 @@ void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
|
||||
|
||||
void MonitorExitStub::emit_code(LIR_Assembler* ce) {
|
||||
__ bind(_entry);
|
||||
if (_compute_lock) {
|
||||
// lock_reg was destroyed by fast unlocking attempt => recompute it
|
||||
ce->monitor_address(_monitor_ix, _lock_reg);
|
||||
}
|
||||
|
||||
// lock_reg was destroyed by fast unlocking attempt => recompute it
|
||||
ce->monitor_address(_monitor_ix, _lock_reg);
|
||||
|
||||
ce->store_parameter(_lock_reg->as_register(), 0);
|
||||
// note: non-blocking leaf routine => no call info needed
|
||||
StubId exit_id;
|
||||
|
||||
@ -383,13 +383,6 @@ LIR_Opr FrameMap::stack_pointer() {
|
||||
return FrameMap::sp_opr;
|
||||
}
|
||||
|
||||
|
||||
// JSR 292
|
||||
LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() {
|
||||
return LIR_OprFact::illegalOpr; // Not needed on aarch64
|
||||
}
|
||||
|
||||
|
||||
bool FrameMap::validate_frame() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -409,7 +409,7 @@ int LIR_Assembler::emit_unwind_handler() {
|
||||
MonitorExitStub* stub = nullptr;
|
||||
if (method()->is_synchronized()) {
|
||||
monitor_address(0, FrameMap::r0_opr);
|
||||
stub = new MonitorExitStub(FrameMap::r0_opr, true, 0);
|
||||
stub = new MonitorExitStub(FrameMap::r0_opr, 0);
|
||||
__ unlock_object(r5, r4, r0, r6, *stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
@ -2481,7 +2481,6 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
|
||||
Register lock = op->lock_opr()->as_register();
|
||||
Register temp = op->scratch_opr()->as_register();
|
||||
if (op->code() == lir_lock) {
|
||||
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
|
||||
// add debug info for NullPointerException only if one is possible
|
||||
int null_check_offset = __ lock_object(hdr, obj, lock, temp, *op->stub()->entry());
|
||||
if (op->info() != nullptr) {
|
||||
@ -2489,7 +2488,6 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
|
||||
}
|
||||
// done
|
||||
} else if (op->code() == lir_unlock) {
|
||||
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
|
||||
__ unlock_object(hdr, obj, lock, temp, *op->stub()->entry());
|
||||
} else {
|
||||
Unimplemented();
|
||||
|
||||
@ -59,28 +59,28 @@ void C1_MacroAssembler::float_cmp(bool is_float, int unordered_result,
|
||||
}
|
||||
}
|
||||
|
||||
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
|
||||
assert_different_registers(hdr, obj, disp_hdr, temp, rscratch2);
|
||||
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register basic_lock, Register temp, Label& slow_case) {
|
||||
assert_different_registers(hdr, obj, basic_lock, temp, rscratch2);
|
||||
int null_check_offset = -1;
|
||||
|
||||
verify_oop(obj);
|
||||
|
||||
// save object being locked into the BasicObjectLock
|
||||
str(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
|
||||
str(obj, Address(basic_lock, BasicObjectLock::obj_offset()));
|
||||
|
||||
null_check_offset = offset();
|
||||
|
||||
lightweight_lock(disp_hdr, obj, hdr, temp, rscratch2, slow_case);
|
||||
lightweight_lock(basic_lock, obj, hdr, temp, rscratch2, slow_case);
|
||||
|
||||
return null_check_offset;
|
||||
}
|
||||
|
||||
|
||||
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
|
||||
assert_different_registers(hdr, obj, disp_hdr, temp, rscratch2);
|
||||
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register basic_lock, Register temp, Label& slow_case) {
|
||||
assert_different_registers(hdr, obj, basic_lock, temp, rscratch2);
|
||||
|
||||
// load object
|
||||
ldr(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
|
||||
ldr(obj, Address(basic_lock, BasicObjectLock::obj_offset()));
|
||||
verify_oop(obj);
|
||||
|
||||
lightweight_unlock(obj, hdr, temp, rscratch2, slow_case);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -55,19 +55,19 @@ using MacroAssembler::null_check;
|
||||
Register result);
|
||||
|
||||
// locking
|
||||
// hdr : must be r0, contents destroyed
|
||||
// obj : must point to the object to lock, contents preserved
|
||||
// disp_hdr: must point to the displaced header location, contents preserved
|
||||
// temp : temporary register, must not be rscratch1 or rscratch2
|
||||
// hdr : must be r0, contents destroyed
|
||||
// obj : must point to the object to lock, contents preserved
|
||||
// basic_lock: must point to the basic lock, contents preserved
|
||||
// temp : temporary register, must not be rscratch1 or rscratch2
|
||||
// returns code offset at which to add null check debug information
|
||||
int lock_object (Register swap, Register obj, Register disp_hdr, Register temp, Label& slow_case);
|
||||
int lock_object (Register swap, Register obj, Register basic_lock, Register temp, Label& slow_case);
|
||||
|
||||
// unlocking
|
||||
// hdr : contents destroyed
|
||||
// obj : must point to the object to lock, contents preserved
|
||||
// disp_hdr: must be r0 & must point to the displaced header location, contents destroyed
|
||||
// temp : temporary register, must not be rscratch1 or rscratch2
|
||||
void unlock_object(Register swap, Register obj, Register lock, Register temp, Label& slow_case);
|
||||
// hdr : contents destroyed
|
||||
// obj : must point to the object to lock, contents preserved
|
||||
// basic_lock: must be r0 & must point to the basic lock, contents destroyed
|
||||
// temp : temporary register, must not be rscratch1 or rscratch2
|
||||
void unlock_object(Register swap, Register obj, Register basic_lock, Register temp, Label& slow_case);
|
||||
|
||||
void initialize_object(
|
||||
Register obj, // result: pointer to object after successful allocation
|
||||
|
||||
@ -53,7 +53,6 @@ define_pd_global(size_t, CodeCacheExpansionSize, 32*K );
|
||||
define_pd_global(size_t, CodeCacheMinBlockLength, 1);
|
||||
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
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);
|
||||
|
||||
@ -2203,114 +2203,117 @@ void C2_MacroAssembler::sve_gen_mask_imm(PRegister dst, BasicType bt, uint32_t l
|
||||
// Pack active elements of src, under the control of mask, into the lowest-numbered elements of dst.
|
||||
// Any remaining elements of dst will be filled with zero.
|
||||
// Clobbers: rscratch1
|
||||
// Preserves: src, mask
|
||||
// Preserves: mask, vzr
|
||||
void C2_MacroAssembler::sve_compress_short(FloatRegister dst, FloatRegister src, PRegister mask,
|
||||
FloatRegister vtmp1, FloatRegister vtmp2,
|
||||
PRegister pgtmp) {
|
||||
FloatRegister vzr, FloatRegister vtmp,
|
||||
PRegister pgtmp, unsigned vector_length_in_bytes) {
|
||||
assert(pgtmp->is_governing(), "This register has to be a governing predicate register");
|
||||
assert_different_registers(dst, src, vtmp1, vtmp2);
|
||||
// When called by sve_compress_byte, src and vtmp may be the same register.
|
||||
assert_different_registers(dst, src, vzr);
|
||||
assert_different_registers(dst, vtmp, vzr);
|
||||
assert_different_registers(mask, pgtmp);
|
||||
|
||||
// Example input: src = 8888 7777 6666 5555 4444 3333 2222 1111
|
||||
// mask = 0001 0000 0000 0001 0001 0000 0001 0001
|
||||
// Expected result: dst = 0000 0000 0000 8888 5555 4444 2222 1111
|
||||
sve_dup(vtmp2, H, 0);
|
||||
// high <-- low
|
||||
// Example input: src = hh gg ff ee dd cc bb aa, one character is 8 bits.
|
||||
// mask = 01 00 00 01 01 00 01 01, one character is 1 bit.
|
||||
// Expected result: dst = 00 00 00 hh ee dd bb aa
|
||||
|
||||
// Extend lowest half to type INT.
|
||||
// dst = 00004444 00003333 00002222 00001111
|
||||
// dst = 00dd 00cc 00bb 00aa
|
||||
sve_uunpklo(dst, S, src);
|
||||
// pgtmp = 00000001 00000000 00000001 00000001
|
||||
// pgtmp = 0001 0000 0001 0001
|
||||
sve_punpklo(pgtmp, mask);
|
||||
// Pack the active elements in size of type INT to the right,
|
||||
// and fill the remainings with zero.
|
||||
// dst = 00000000 00004444 00002222 00001111
|
||||
// dst = 0000 00dd 00bb 00aa
|
||||
sve_compact(dst, S, dst, pgtmp);
|
||||
// Narrow the result back to type SHORT.
|
||||
// dst = 0000 0000 0000 0000 0000 4444 2222 1111
|
||||
sve_uzp1(dst, H, dst, vtmp2);
|
||||
// dst = 00 00 00 00 00 dd bb aa
|
||||
sve_uzp1(dst, H, dst, vzr);
|
||||
|
||||
// Return if the vector length is no more than MaxVectorSize/2, since the
|
||||
// highest half is invalid.
|
||||
if (vector_length_in_bytes <= (MaxVectorSize >> 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Count the active elements of lowest half.
|
||||
// rscratch1 = 3
|
||||
sve_cntp(rscratch1, S, ptrue, pgtmp);
|
||||
|
||||
// Repeat to the highest half.
|
||||
// pgtmp = 00000001 00000000 00000000 00000001
|
||||
// pgtmp = 0001 0000 0000 0001
|
||||
sve_punpkhi(pgtmp, mask);
|
||||
// vtmp1 = 00008888 00007777 00006666 00005555
|
||||
sve_uunpkhi(vtmp1, S, src);
|
||||
// vtmp1 = 00000000 00000000 00008888 00005555
|
||||
sve_compact(vtmp1, S, vtmp1, pgtmp);
|
||||
// vtmp1 = 0000 0000 0000 0000 0000 0000 8888 5555
|
||||
sve_uzp1(vtmp1, H, vtmp1, vtmp2);
|
||||
// vtmp = 00hh 00gg 00ff 00ee
|
||||
sve_uunpkhi(vtmp, S, src);
|
||||
// vtmp = 0000 0000 00hh 00ee
|
||||
sve_compact(vtmp, S, vtmp, pgtmp);
|
||||
// vtmp = 00 00 00 00 00 00 hh ee
|
||||
sve_uzp1(vtmp, H, vtmp, vzr);
|
||||
|
||||
// Compressed low: dst = 0000 0000 0000 0000 0000 4444 2222 1111
|
||||
// Compressed high: vtmp1 = 0000 0000 0000 0000 0000 0000 8888 5555
|
||||
// Left shift(cross lane) compressed high with TRUE_CNT lanes,
|
||||
// TRUE_CNT is the number of active elements in the compressed low.
|
||||
neg(rscratch1, rscratch1);
|
||||
// vtmp2 = {4 3 2 1 0 -1 -2 -3}
|
||||
sve_index(vtmp2, H, rscratch1, 1);
|
||||
// vtmp1 = 0000 0000 0000 8888 5555 0000 0000 0000
|
||||
sve_tbl(vtmp1, H, vtmp1, vtmp2);
|
||||
|
||||
// Combine the compressed high(after shifted) with the compressed low.
|
||||
// dst = 0000 0000 0000 8888 5555 4444 2222 1111
|
||||
sve_orr(dst, dst, vtmp1);
|
||||
// pgtmp = 00 00 00 00 00 01 01 01
|
||||
sve_whilelt(pgtmp, H, zr, rscratch1);
|
||||
// Compressed low: dst = 00 00 00 00 00 dd bb aa
|
||||
// Compressed high: vtmp = 00 00 00 00 00 00 hh ee
|
||||
// Combine the compressed low with the compressed high:
|
||||
// dst = 00 00 00 hh ee dd bb aa
|
||||
sve_splice(dst, H, pgtmp, vtmp);
|
||||
}
|
||||
|
||||
// Clobbers: rscratch1, rscratch2
|
||||
// Preserves: src, mask
|
||||
void C2_MacroAssembler::sve_compress_byte(FloatRegister dst, FloatRegister src, PRegister mask,
|
||||
FloatRegister vtmp1, FloatRegister vtmp2,
|
||||
FloatRegister vtmp3, FloatRegister vtmp4,
|
||||
PRegister ptmp, PRegister pgtmp) {
|
||||
FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3,
|
||||
PRegister ptmp, PRegister pgtmp, unsigned vector_length_in_bytes) {
|
||||
assert(pgtmp->is_governing(), "This register has to be a governing predicate register");
|
||||
assert_different_registers(dst, src, vtmp1, vtmp2, vtmp3, vtmp4);
|
||||
assert_different_registers(dst, src, vtmp1, vtmp2, vtmp3);
|
||||
assert_different_registers(mask, ptmp, pgtmp);
|
||||
// Example input: src = 88 77 66 55 44 33 22 11
|
||||
// mask = 01 00 00 01 01 00 01 01
|
||||
// Expected result: dst = 00 00 00 88 55 44 22 11
|
||||
// high <-- low
|
||||
// Example input: src = q p n m l k j i h g f e d c b a, one character is 8 bits.
|
||||
// mask = 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 1, one character is 1 bit.
|
||||
// Expected result: dst = 0 0 0 0 0 0 0 0 0 0 0 p i g c a
|
||||
FloatRegister vzr = vtmp3;
|
||||
sve_dup(vzr, B, 0);
|
||||
|
||||
sve_dup(vtmp4, B, 0);
|
||||
// Extend lowest half to type SHORT.
|
||||
// vtmp1 = 0044 0033 0022 0011
|
||||
// vtmp1 = 0h 0g 0f 0e 0d 0c 0b 0a
|
||||
sve_uunpklo(vtmp1, H, src);
|
||||
// ptmp = 0001 0000 0001 0001
|
||||
// ptmp = 00 01 00 00 00 01 00 01
|
||||
sve_punpklo(ptmp, mask);
|
||||
// Pack the active elements in size of type SHORT to the right,
|
||||
// and fill the remainings with zero.
|
||||
// dst = 00 00 00 00 00 0g 0c 0a
|
||||
unsigned extended_size = vector_length_in_bytes << 1;
|
||||
sve_compress_short(dst, vtmp1, ptmp, vzr, vtmp2, pgtmp, extended_size > MaxVectorSize ? MaxVectorSize : extended_size);
|
||||
// Narrow the result back to type BYTE.
|
||||
// dst = 0 0 0 0 0 0 0 0 0 0 0 0 0 g c a
|
||||
sve_uzp1(dst, B, dst, vzr);
|
||||
|
||||
// Return if the vector length is no more than MaxVectorSize/2, since the
|
||||
// highest half is invalid.
|
||||
if (vector_length_in_bytes <= (MaxVectorSize >> 1)) {
|
||||
return;
|
||||
}
|
||||
// Count the active elements of lowest half.
|
||||
// rscratch2 = 3
|
||||
sve_cntp(rscratch2, H, ptrue, ptmp);
|
||||
// Pack the active elements in size of type SHORT to the right,
|
||||
// and fill the remainings with zero.
|
||||
// dst = 0000 0044 0022 0011
|
||||
sve_compress_short(dst, vtmp1, ptmp, vtmp2, vtmp3, pgtmp);
|
||||
// Narrow the result back to type BYTE.
|
||||
// dst = 00 00 00 00 00 44 22 11
|
||||
sve_uzp1(dst, B, dst, vtmp4);
|
||||
|
||||
// Repeat to the highest half.
|
||||
// ptmp = 0001 0000 0000 0001
|
||||
// ptmp = 00 01 00 00 00 00 00 01
|
||||
sve_punpkhi(ptmp, mask);
|
||||
// vtmp1 = 0088 0077 0066 0055
|
||||
// vtmp2 = 0q 0p 0n 0m 0l 0k 0j 0i
|
||||
sve_uunpkhi(vtmp2, H, src);
|
||||
// vtmp1 = 0000 0000 0088 0055
|
||||
sve_compress_short(vtmp1, vtmp2, ptmp, vtmp3, vtmp4, pgtmp);
|
||||
// vtmp1 = 00 00 00 00 00 00 0p 0i
|
||||
sve_compress_short(vtmp1, vtmp2, ptmp, vzr, vtmp2, pgtmp, extended_size - MaxVectorSize);
|
||||
// vtmp1 = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 p i
|
||||
sve_uzp1(vtmp1, B, vtmp1, vzr);
|
||||
|
||||
sve_dup(vtmp4, B, 0);
|
||||
// vtmp1 = 00 00 00 00 00 00 88 55
|
||||
sve_uzp1(vtmp1, B, vtmp1, vtmp4);
|
||||
|
||||
// Compressed low: dst = 00 00 00 00 00 44 22 11
|
||||
// Compressed high: vtmp1 = 00 00 00 00 00 00 88 55
|
||||
// Left shift(cross lane) compressed high with TRUE_CNT lanes,
|
||||
// TRUE_CNT is the number of active elements in the compressed low.
|
||||
neg(rscratch2, rscratch2);
|
||||
// vtmp2 = {4 3 2 1 0 -1 -2 -3}
|
||||
sve_index(vtmp2, B, rscratch2, 1);
|
||||
// vtmp1 = 00 00 00 88 55 00 00 00
|
||||
sve_tbl(vtmp1, B, vtmp1, vtmp2);
|
||||
// Combine the compressed high(after shifted) with the compressed low.
|
||||
// dst = 00 00 00 88 55 44 22 11
|
||||
sve_orr(dst, dst, vtmp1);
|
||||
// ptmp = 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
|
||||
sve_whilelt(ptmp, B, zr, rscratch2);
|
||||
// Compressed low: dst = 0 0 0 0 0 0 0 0 0 0 0 0 0 g c a
|
||||
// Compressed high: vtmp1 = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 p i
|
||||
// Combine the compressed low with the compressed high:
|
||||
// dst = 0 0 0 0 0 0 0 0 0 0 0 p i g c a
|
||||
sve_splice(dst, B, ptmp, vtmp1);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::neon_reverse_bits(FloatRegister dst, FloatRegister src, BasicType bt, bool isQ) {
|
||||
@ -2771,3 +2774,90 @@ void C2_MacroAssembler::select_from_two_vectors(FloatRegister dst, FloatRegister
|
||||
select_from_two_vectors_neon(dst, src1, src2, dst, tmp, vector_length_in_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
// Vector expand implementation. Elements from the src vector are expanded into
|
||||
// the dst vector under the control of the vector mask.
|
||||
// Since there are no native instructions directly corresponding to expand before
|
||||
// SVE2p2, the following implementations mainly leverages the TBL instruction to
|
||||
// implement expand. To compute the index input for TBL, the prefix sum algorithm
|
||||
// (https://en.wikipedia.org/wiki/Prefix_sum) is used. The same algorithm is used
|
||||
// for NEON and SVE, but with different instructions where appropriate.
|
||||
|
||||
// Vector expand implementation for NEON.
|
||||
//
|
||||
// An example of 128-bit Byte vector:
|
||||
// Data direction: high <== low
|
||||
// Input:
|
||||
// src = g f e d c b a 9 8 7 6 5 4 3 2 1
|
||||
// mask = 0 0 -1 -1 0 0 -1 -1 0 0 -1 -1 0 0 -1 -1
|
||||
// Expected result:
|
||||
// dst = 0 0 8 7 0 0 6 5 0 0 4 3 0 0 2 1
|
||||
void C2_MacroAssembler::vector_expand_neon(FloatRegister dst, FloatRegister src, FloatRegister mask,
|
||||
FloatRegister tmp1, FloatRegister tmp2, BasicType bt,
|
||||
int vector_length_in_bytes) {
|
||||
assert(vector_length_in_bytes <= 16, "the vector length in bytes for NEON must be <= 16");
|
||||
assert_different_registers(dst, src, mask, tmp1, tmp2);
|
||||
// Since the TBL instruction only supports byte table, we need to
|
||||
// compute indices in byte type for all types.
|
||||
SIMD_Arrangement size = vector_length_in_bytes == 16 ? T16B : T8B;
|
||||
// tmp1 = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
dup(tmp1, size, zr);
|
||||
// dst = 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
|
||||
negr(dst, size, mask);
|
||||
// Calculate vector index for TBL with prefix sum algorithm.
|
||||
// dst = 8 8 8 7 6 6 6 5 4 4 4 3 2 2 2 1
|
||||
for (int i = 1; i < vector_length_in_bytes; i <<= 1) {
|
||||
ext(tmp2, size, tmp1, dst, vector_length_in_bytes - i);
|
||||
addv(dst, size, tmp2, dst);
|
||||
}
|
||||
// tmp2 = 0 0 -1 -1 0 0 -1 -1 0 0 -1 -1 0 0 -1 -1
|
||||
orr(tmp2, size, mask, mask);
|
||||
// tmp2 = 0 0 8 7 0 0 6 5 0 0 4 3 0 0 2 1
|
||||
bsl(tmp2, size, dst, tmp1);
|
||||
// tmp1 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||
movi(tmp1, size, 1);
|
||||
// dst = -1 -1 7 6 -1 -1 5 4 -1 -1 3 2 -1 -1 1 0
|
||||
subv(dst, size, tmp2, tmp1);
|
||||
// dst = 0 0 8 7 0 0 6 5 0 0 4 3 0 0 2 1
|
||||
tbl(dst, size, src, 1, dst);
|
||||
}
|
||||
|
||||
// Vector expand implementation for SVE.
|
||||
//
|
||||
// An example of 128-bit Short vector:
|
||||
// Data direction: high <== low
|
||||
// Input:
|
||||
// src = gf ed cb a9 87 65 43 21
|
||||
// pg = 00 01 00 01 00 01 00 01
|
||||
// Expected result:
|
||||
// dst = 00 87 00 65 00 43 00 21
|
||||
void C2_MacroAssembler::vector_expand_sve(FloatRegister dst, FloatRegister src, PRegister pg,
|
||||
FloatRegister tmp1, FloatRegister tmp2, BasicType bt,
|
||||
int vector_length_in_bytes) {
|
||||
assert(UseSVE > 0, "expand implementation only for SVE");
|
||||
assert_different_registers(dst, src, tmp1, tmp2);
|
||||
SIMD_RegVariant size = elemType_to_regVariant(bt);
|
||||
|
||||
// tmp1 = 00 00 00 00 00 00 00 00
|
||||
sve_dup(tmp1, size, 0);
|
||||
sve_movprfx(tmp2, tmp1);
|
||||
// tmp2 = 00 01 00 01 00 01 00 01
|
||||
sve_cpy(tmp2, size, pg, 1, true);
|
||||
// Calculate vector index for TBL with prefix sum algorithm.
|
||||
// tmp2 = 04 04 03 03 02 02 01 01
|
||||
for (int i = type2aelembytes(bt); i < vector_length_in_bytes; i <<= 1) {
|
||||
sve_movprfx(dst, tmp1);
|
||||
// The EXT instruction operates on the full-width sve register. The correct
|
||||
// index calculation method is:
|
||||
// vector_length_in_bytes - i + MaxVectorSize - vector_length_in_bytes =>
|
||||
// MaxVectorSize - i.
|
||||
sve_ext(dst, tmp2, MaxVectorSize - i);
|
||||
sve_add(tmp2, size, dst, tmp2);
|
||||
}
|
||||
// dst = 00 04 00 03 00 02 00 01
|
||||
sve_sel(dst, size, pg, tmp2, tmp1);
|
||||
// dst = -1 03 -1 02 -1 01 -1 00
|
||||
sve_sub(dst, size, 1);
|
||||
// dst = 00 87 00 65 00 43 00 21
|
||||
sve_tbl(dst, size, src, dst);
|
||||
}
|
||||
@ -173,13 +173,12 @@
|
||||
// lowest-numbered elements of dst. Any remaining elements of dst will
|
||||
// be filled with zero.
|
||||
void sve_compress_byte(FloatRegister dst, FloatRegister src, PRegister mask,
|
||||
FloatRegister vtmp1, FloatRegister vtmp2,
|
||||
FloatRegister vtmp3, FloatRegister vtmp4,
|
||||
PRegister ptmp, PRegister pgtmp);
|
||||
FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3,
|
||||
PRegister ptmp, PRegister pgtmp, unsigned vector_length_in_bytes);
|
||||
|
||||
void sve_compress_short(FloatRegister dst, FloatRegister src, PRegister mask,
|
||||
FloatRegister vtmp1, FloatRegister vtmp2,
|
||||
PRegister pgtmp);
|
||||
FloatRegister vzr, FloatRegister vtmp,
|
||||
PRegister pgtmp, unsigned vector_length_in_bytes);
|
||||
|
||||
void neon_reverse_bits(FloatRegister dst, FloatRegister src, BasicType bt, bool isQ);
|
||||
|
||||
@ -204,4 +203,10 @@
|
||||
FloatRegister index, FloatRegister tmp, BasicType bt,
|
||||
unsigned vector_length_in_bytes);
|
||||
|
||||
void vector_expand_neon(FloatRegister dst, FloatRegister src, FloatRegister mask,
|
||||
FloatRegister tmp1, FloatRegister tmp2, BasicType bt,
|
||||
int vector_length_in_bytes);
|
||||
void vector_expand_sve(FloatRegister dst, FloatRegister src, PRegister pg,
|
||||
FloatRegister tmp1, FloatRegister tmp2, BasicType bt,
|
||||
int vector_length_in_bytes);
|
||||
#endif // CPU_AARCH64_C2_MACROASSEMBLER_AARCH64_HPP
|
||||
|
||||
@ -55,7 +55,6 @@ define_pd_global(size_t, InitialCodeCacheSize, 2496*K); // Integral multip
|
||||
define_pd_global(size_t, CodeCacheExpansionSize, 64*K);
|
||||
|
||||
// Ergonomics related flags
|
||||
define_pd_global(uint64_t,MaxRAM, 128ULL*G);
|
||||
define_pd_global(intx, RegisterCostAreaRatio, 16000);
|
||||
|
||||
// Peephole and CISC spilling both break the graph, and so makes the
|
||||
|
||||
@ -228,8 +228,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
nmethod* nm = sender_blob->as_nmethod_or_null();
|
||||
if (nm != nullptr) {
|
||||
if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc) ||
|
||||
nm->method()->is_method_handle_intrinsic()) {
|
||||
if (nm->is_deopt_entry(sender_pc) || nm->method()->is_method_handle_intrinsic()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -454,48 +453,6 @@ JavaThread** frame::saved_thread_address(const frame& f) {
|
||||
return thread_addr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::verify_deopt_original_pc
|
||||
//
|
||||
// Verifies the calculated original PC of a deoptimization PC for the
|
||||
// given unextended SP.
|
||||
#ifdef ASSERT
|
||||
void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp) {
|
||||
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_inclusive(original_pc),
|
||||
"original PC must be in the main code section of the compiled method (or must be immediately following it)");
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::adjust_unextended_sp
|
||||
#ifdef ASSERT
|
||||
void frame::adjust_unextended_sp() {
|
||||
// On aarch64, sites calling method handle intrinsics and lambda forms are treated
|
||||
// as any other call site. Therefore, no special action is needed when we are
|
||||
// returning to any of these call sites.
|
||||
|
||||
if (_cb != nullptr) {
|
||||
nmethod* sender_nm = _cb->as_nmethod_or_null();
|
||||
if (sender_nm != nullptr) {
|
||||
// If the sender PC is a deoptimization point, get the original PC.
|
||||
if (sender_nm->is_deopt_entry(_pc) ||
|
||||
sender_nm->is_deopt_mh_entry(_pc)) {
|
||||
verify_deopt_original_pc(sender_nm, _unextended_sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::sender_for_interpreter_frame
|
||||
frame frame::sender_for_interpreter_frame(RegisterMap* map) const {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -141,8 +141,6 @@
|
||||
int _offset_unextended_sp; // for use in stack-chunk frames
|
||||
};
|
||||
|
||||
void adjust_unextended_sp() NOT_DEBUG_RETURN;
|
||||
|
||||
// true means _sp value is correct and we can use it to get the sender's sp
|
||||
// of the compiled frame, otherwise, _sp value may be invalid and we can use
|
||||
// _fp to get the sender's sp if PreserveFramePointer is enabled.
|
||||
@ -152,11 +150,6 @@
|
||||
return (intptr_t*) addr_at(offset);
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
// Used in frame::sender_for_{interpreter,compiled}_frame
|
||||
static void verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp);
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
|
||||
|
||||
@ -116,8 +116,6 @@ inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) {
|
||||
}
|
||||
|
||||
inline void frame::setup(address pc) {
|
||||
adjust_unextended_sp();
|
||||
|
||||
address original_pc = get_deopt_original_pc();
|
||||
if (original_pc != nullptr) {
|
||||
_pc = original_pc;
|
||||
@ -223,7 +221,6 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) {
|
||||
// assert(_pc != nullptr, "no pc?");
|
||||
|
||||
_cb = CodeCache::find_blob(_pc);
|
||||
adjust_unextended_sp();
|
||||
|
||||
address original_pc = get_deopt_original_pc();
|
||||
if (original_pc != nullptr) {
|
||||
|
||||
@ -86,15 +86,48 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm
|
||||
}
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
|
||||
Register start, Register count, Register scratch, RegSet saved_regs) {
|
||||
__ push(saved_regs, sp);
|
||||
assert_different_registers(start, count, scratch);
|
||||
assert_different_registers(c_rarg0, count);
|
||||
__ mov(c_rarg0, start);
|
||||
__ mov(c_rarg1, count);
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_post_entry), 2);
|
||||
__ pop(saved_regs, sp);
|
||||
void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm,
|
||||
DecoratorSet decorators,
|
||||
Register start,
|
||||
Register count,
|
||||
Register scratch,
|
||||
RegSet saved_regs) {
|
||||
|
||||
Label done;
|
||||
Label loop;
|
||||
Label next;
|
||||
|
||||
__ cbz(count, done);
|
||||
|
||||
// Calculate the number of card marks to set. Since the object might start and
|
||||
// end within a card, we need to calculate this via the card table indexes of
|
||||
// the actual start and last addresses covered by the object.
|
||||
// Temporarily use the count register for the last element address.
|
||||
__ lea(count, Address(start, count, Address::lsl(LogBytesPerHeapOop))); // end = start + count << LogBytesPerHeapOop
|
||||
__ sub(count, count, BytesPerHeapOop); // Use last element address for end.
|
||||
|
||||
__ lsr(start, start, CardTable::card_shift());
|
||||
__ lsr(count, count, CardTable::card_shift());
|
||||
__ sub(count, count, start); // Number of bytes to mark - 1.
|
||||
|
||||
// Add card table base offset to start.
|
||||
__ ldr(scratch, Address(rthread, in_bytes(G1ThreadLocalData::card_table_base_offset())));
|
||||
__ add(start, start, scratch);
|
||||
|
||||
__ bind(loop);
|
||||
if (UseCondCardMark) {
|
||||
__ ldrb(scratch, Address(start, count));
|
||||
// Instead of loading clean_card_val and comparing, we exploit the fact that
|
||||
// the LSB of non-clean cards is always 0, and the LSB of clean cards 1.
|
||||
__ tbz(scratch, 0, next);
|
||||
}
|
||||
static_assert(G1CardTable::dirty_card_val() == 0, "must be to use zr");
|
||||
__ strb(zr, Address(start, count));
|
||||
__ bind(next);
|
||||
__ subs(count, count, 1);
|
||||
__ br(Assembler::GE, loop);
|
||||
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
static void generate_queue_test_and_insertion(MacroAssembler* masm, ByteSize index_offset, ByteSize buffer_offset, Label& runtime,
|
||||
@ -199,13 +232,17 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
|
||||
|
||||
}
|
||||
|
||||
static void generate_post_barrier_fast_path(MacroAssembler* masm,
|
||||
const Register store_addr,
|
||||
const Register new_val,
|
||||
const Register tmp1,
|
||||
const Register tmp2,
|
||||
Label& done,
|
||||
bool new_val_may_be_null) {
|
||||
static void generate_post_barrier(MacroAssembler* masm,
|
||||
const Register store_addr,
|
||||
const Register new_val,
|
||||
const Register thread,
|
||||
const Register tmp1,
|
||||
const Register tmp2,
|
||||
Label& done,
|
||||
bool new_val_may_be_null) {
|
||||
assert(thread == rthread, "must be");
|
||||
assert_different_registers(store_addr, new_val, thread, tmp1, tmp2, noreg, rscratch1);
|
||||
|
||||
// Does store cross heap regions?
|
||||
__ eor(tmp1, store_addr, new_val); // tmp1 := store address ^ new value
|
||||
__ lsr(tmp1, tmp1, G1HeapRegion::LogOfHRGrainBytes); // tmp1 := ((store address ^ new value) >> LogOfHRGrainBytes)
|
||||
@ -214,33 +251,19 @@ static void generate_post_barrier_fast_path(MacroAssembler* masm,
|
||||
if (new_val_may_be_null) {
|
||||
__ cbz(new_val, done);
|
||||
}
|
||||
// Storing region crossing non-null, is card young?
|
||||
// Storing region crossing non-null.
|
||||
__ lsr(tmp1, store_addr, CardTable::card_shift()); // tmp1 := card address relative to card table base
|
||||
__ load_byte_map_base(tmp2); // tmp2 := card table base address
|
||||
__ add(tmp1, tmp1, tmp2); // tmp1 := card address
|
||||
__ ldrb(tmp2, Address(tmp1)); // tmp2 := card
|
||||
__ cmpw(tmp2, (int)G1CardTable::g1_young_card_val()); // tmp2 := card == young_card_val?
|
||||
}
|
||||
|
||||
static void generate_post_barrier_slow_path(MacroAssembler* masm,
|
||||
const Register thread,
|
||||
const Register tmp1,
|
||||
const Register tmp2,
|
||||
Label& done,
|
||||
Label& runtime) {
|
||||
__ membar(Assembler::StoreLoad); // StoreLoad membar
|
||||
__ ldrb(tmp2, Address(tmp1)); // tmp2 := card
|
||||
__ cbzw(tmp2, done);
|
||||
// Storing a region crossing, non-null oop, card is clean.
|
||||
// Dirty card and log.
|
||||
STATIC_ASSERT(CardTable::dirty_card_val() == 0);
|
||||
__ strb(zr, Address(tmp1)); // *(card address) := dirty_card_val
|
||||
generate_queue_test_and_insertion(masm,
|
||||
G1ThreadLocalData::dirty_card_queue_index_offset(),
|
||||
G1ThreadLocalData::dirty_card_queue_buffer_offset(),
|
||||
runtime,
|
||||
thread, tmp1, tmp2, rscratch1);
|
||||
__ b(done);
|
||||
Address card_table_addr(thread, in_bytes(G1ThreadLocalData::card_table_base_offset()));
|
||||
__ ldr(tmp2, card_table_addr); // tmp2 := card table base address
|
||||
if (UseCondCardMark) {
|
||||
__ ldrb(rscratch1, Address(tmp1, tmp2)); // rscratch1 := card
|
||||
// Instead of loading clean_card_val and comparing, we exploit the fact that
|
||||
// the LSB of non-clean cards is always 0, and the LSB of clean cards 1.
|
||||
__ tbz(rscratch1, 0, done);
|
||||
}
|
||||
static_assert(G1CardTable::dirty_card_val() == 0, "must be to use zr");
|
||||
__ strb(zr, Address(tmp1, tmp2)); // *(card address) := dirty_card_val
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
|
||||
@ -249,27 +272,8 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
|
||||
Register thread,
|
||||
Register tmp1,
|
||||
Register tmp2) {
|
||||
assert(thread == rthread, "must be");
|
||||
assert_different_registers(store_addr, new_val, thread, tmp1, tmp2,
|
||||
rscratch1);
|
||||
assert(store_addr != noreg && new_val != noreg && tmp1 != noreg
|
||||
&& tmp2 != noreg, "expecting a register");
|
||||
|
||||
Label done;
|
||||
Label runtime;
|
||||
|
||||
generate_post_barrier_fast_path(masm, store_addr, new_val, tmp1, tmp2, done, true /* new_val_may_be_null */);
|
||||
// If card is young, jump to done
|
||||
__ br(Assembler::EQ, done);
|
||||
generate_post_barrier_slow_path(masm, thread, tmp1, tmp2, done, runtime);
|
||||
|
||||
__ bind(runtime);
|
||||
// save the live input values
|
||||
RegSet saved = RegSet::of(store_addr);
|
||||
__ push(saved, sp);
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), tmp1, thread);
|
||||
__ pop(saved, sp);
|
||||
|
||||
generate_post_barrier(masm, store_addr, new_val, thread, tmp1, tmp2, done, false /* new_val_may_be_null */);
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
@ -329,38 +333,10 @@ void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm,
|
||||
Register thread,
|
||||
Register tmp1,
|
||||
Register tmp2,
|
||||
G1PostBarrierStubC2* stub) {
|
||||
assert(thread == rthread, "must be");
|
||||
assert_different_registers(store_addr, new_val, thread, tmp1, tmp2,
|
||||
rscratch1);
|
||||
assert(store_addr != noreg && new_val != noreg && tmp1 != noreg
|
||||
&& tmp2 != noreg, "expecting a register");
|
||||
|
||||
stub->initialize_registers(thread, tmp1, tmp2);
|
||||
|
||||
bool new_val_may_be_null = (stub->barrier_data() & G1C2BarrierPostNotNull) == 0;
|
||||
generate_post_barrier_fast_path(masm, store_addr, new_val, tmp1, tmp2, *stub->continuation(), new_val_may_be_null);
|
||||
// If card is not young, jump to stub (slow path)
|
||||
__ br(Assembler::NE, *stub->entry());
|
||||
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::generate_c2_post_barrier_stub(MacroAssembler* masm,
|
||||
G1PostBarrierStubC2* stub) const {
|
||||
Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
|
||||
Label runtime;
|
||||
Register thread = stub->thread();
|
||||
Register tmp1 = stub->tmp1(); // tmp1 holds the card address.
|
||||
Register tmp2 = stub->tmp2();
|
||||
assert(stub->tmp3() == noreg, "not needed in this platform");
|
||||
|
||||
__ bind(*stub->entry());
|
||||
generate_post_barrier_slow_path(masm, thread, tmp1, tmp2, *stub->continuation(), runtime);
|
||||
|
||||
__ bind(runtime);
|
||||
generate_c2_barrier_runtime_call(masm, stub, tmp1, CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry));
|
||||
__ b(*stub->continuation());
|
||||
bool new_val_may_be_null) {
|
||||
Label done;
|
||||
generate_post_barrier(masm, store_addr, new_val, thread, tmp1, tmp2, done, new_val_may_be_null);
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
#endif // COMPILER2
|
||||
@ -456,20 +432,19 @@ void G1BarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrier
|
||||
__ b(*stub->continuation());
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::gen_post_barrier_stub(LIR_Assembler* ce, G1PostBarrierStub* stub) {
|
||||
G1BarrierSetC1* bs = (G1BarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1();
|
||||
__ bind(*stub->entry());
|
||||
assert(stub->addr()->is_register(), "Precondition.");
|
||||
assert(stub->new_val()->is_register(), "Precondition.");
|
||||
Register new_val_reg = stub->new_val()->as_register();
|
||||
__ cbz(new_val_reg, *stub->continuation());
|
||||
ce->store_parameter(stub->addr()->as_pointer_register(), 0);
|
||||
__ far_call(RuntimeAddress(bs->post_barrier_c1_runtime_code_blob()->code_begin()));
|
||||
__ b(*stub->continuation());
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
void G1BarrierSetAssembler::g1_write_barrier_post_c1(MacroAssembler* masm,
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register thread,
|
||||
Register tmp1,
|
||||
Register tmp2) {
|
||||
Label done;
|
||||
generate_post_barrier(masm, store_addr, new_val, thread, tmp1, tmp2, done, true /* new_val_may_be_null */);
|
||||
masm->bind(done);
|
||||
}
|
||||
|
||||
#define __ sasm->
|
||||
|
||||
void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) {
|
||||
@ -521,74 +496,6 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler*
|
||||
__ epilogue();
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* sasm) {
|
||||
__ prologue("g1_post_barrier", false);
|
||||
|
||||
// arg0: store_address
|
||||
Address store_addr(rfp, 2*BytesPerWord);
|
||||
|
||||
BarrierSet* bs = BarrierSet::barrier_set();
|
||||
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
|
||||
CardTable* ct = ctbs->card_table();
|
||||
|
||||
Label done;
|
||||
Label runtime;
|
||||
|
||||
// At this point we know new_value is non-null and the new_value crosses regions.
|
||||
// Must check to see if card is already dirty
|
||||
|
||||
const Register thread = rthread;
|
||||
|
||||
Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
|
||||
Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
|
||||
|
||||
const Register card_offset = rscratch2;
|
||||
// LR is free here, so we can use it to hold the byte_map_base.
|
||||
const Register byte_map_base = lr;
|
||||
|
||||
assert_different_registers(card_offset, byte_map_base, rscratch1);
|
||||
|
||||
__ load_parameter(0, card_offset);
|
||||
__ lsr(card_offset, card_offset, CardTable::card_shift());
|
||||
__ load_byte_map_base(byte_map_base);
|
||||
__ ldrb(rscratch1, Address(byte_map_base, card_offset));
|
||||
__ cmpw(rscratch1, (int)G1CardTable::g1_young_card_val());
|
||||
__ br(Assembler::EQ, done);
|
||||
|
||||
assert((int)CardTable::dirty_card_val() == 0, "must be 0");
|
||||
|
||||
__ membar(Assembler::StoreLoad);
|
||||
__ ldrb(rscratch1, Address(byte_map_base, card_offset));
|
||||
__ cbzw(rscratch1, done);
|
||||
|
||||
// storing region crossing non-null, card is clean.
|
||||
// dirty card and log.
|
||||
__ strb(zr, Address(byte_map_base, card_offset));
|
||||
|
||||
// Convert card offset into an address in card_addr
|
||||
Register card_addr = card_offset;
|
||||
__ add(card_addr, byte_map_base, card_addr);
|
||||
|
||||
__ ldr(rscratch1, queue_index);
|
||||
__ cbz(rscratch1, runtime);
|
||||
__ sub(rscratch1, rscratch1, wordSize);
|
||||
__ str(rscratch1, queue_index);
|
||||
|
||||
// Reuse LR to hold buffer_addr
|
||||
const Register buffer_addr = lr;
|
||||
|
||||
__ ldr(buffer_addr, buffer);
|
||||
__ str(card_addr, Address(buffer_addr, rscratch1));
|
||||
__ b(done);
|
||||
|
||||
__ bind(runtime);
|
||||
__ push_call_clobbered_registers();
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), card_addr, thread);
|
||||
__ pop_call_clobbered_registers();
|
||||
__ bind(done);
|
||||
__ epilogue();
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
#endif // COMPILER1
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2025, 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
|
||||
@ -32,9 +32,7 @@
|
||||
class LIR_Assembler;
|
||||
class StubAssembler;
|
||||
class G1PreBarrierStub;
|
||||
class G1PostBarrierStub;
|
||||
class G1PreBarrierStubC2;
|
||||
class G1PostBarrierStubC2;
|
||||
|
||||
class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
|
||||
protected:
|
||||
@ -65,10 +63,15 @@ protected:
|
||||
public:
|
||||
#ifdef COMPILER1
|
||||
void gen_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrierStub* stub);
|
||||
void gen_post_barrier_stub(LIR_Assembler* ce, G1PostBarrierStub* stub);
|
||||
|
||||
void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm);
|
||||
void generate_c1_post_barrier_runtime_stub(StubAssembler* sasm);
|
||||
|
||||
void g1_write_barrier_post_c1(MacroAssembler* masm,
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register thread,
|
||||
Register tmp1,
|
||||
Register tmp2);
|
||||
#endif
|
||||
|
||||
#ifdef COMPILER2
|
||||
@ -87,9 +90,7 @@ public:
|
||||
Register thread,
|
||||
Register tmp1,
|
||||
Register tmp2,
|
||||
G1PostBarrierStubC2* c2_stub);
|
||||
void generate_c2_post_barrier_stub(MacroAssembler* masm,
|
||||
G1PostBarrierStubC2* stub) const;
|
||||
bool new_val_may_be_null);
|
||||
#endif
|
||||
|
||||
void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2024, 2025, 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
|
||||
@ -62,13 +62,13 @@ static void write_barrier_post(MacroAssembler* masm,
|
||||
Register new_val,
|
||||
Register tmp1,
|
||||
Register tmp2) {
|
||||
if (!G1PostBarrierStubC2::needs_barrier(node)) {
|
||||
if (!G1BarrierStubC2::needs_post_barrier(node)) {
|
||||
return;
|
||||
}
|
||||
Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
|
||||
G1BarrierSetAssembler* g1_asm = static_cast<G1BarrierSetAssembler*>(BarrierSet::barrier_set()->barrier_set_assembler());
|
||||
G1PostBarrierStubC2* const stub = G1PostBarrierStubC2::create(node);
|
||||
g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, rthread, tmp1, tmp2, stub);
|
||||
bool new_val_may_be_null = G1BarrierStubC2::post_new_val_may_be_null(node);
|
||||
g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, rthread, tmp1, tmp2, new_val_may_be_null);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
@ -398,14 +398,18 @@ void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register
|
||||
OptoReg::Name BarrierSetAssembler::encode_float_vector_register_size(const Node* node, OptoReg::Name opto_reg) {
|
||||
switch (node->ideal_reg()) {
|
||||
case Op_RegF:
|
||||
case Op_RegI: // RA may place scalar values (Op_RegI/N/L/P) in FP registers when UseFPUForSpilling is enabled
|
||||
case Op_RegN:
|
||||
// No need to refine. The original encoding is already fine to distinguish.
|
||||
assert(opto_reg % 4 == 0, "Float register should only occupy a single slot");
|
||||
assert(opto_reg % 4 == 0, "32-bit register should only occupy a single slot");
|
||||
break;
|
||||
// Use different encoding values of the same fp/vector register to help distinguish different sizes.
|
||||
// Such as V16. The OptoReg::name and its corresponding slot value are
|
||||
// "V16": 64, "V16_H": 65, "V16_J": 66, "V16_K": 67.
|
||||
case Op_RegD:
|
||||
case Op_VecD:
|
||||
case Op_RegL:
|
||||
case Op_RegP:
|
||||
opto_reg &= ~3;
|
||||
opto_reg |= 1;
|
||||
break;
|
||||
|
||||
@ -275,7 +275,6 @@ public:
|
||||
Label* entry();
|
||||
};
|
||||
|
||||
|
||||
class ZStoreBarrierStubC2Aarch64 : public ZStoreBarrierStubC2 {
|
||||
private:
|
||||
bool _deferred_emit;
|
||||
|
||||
@ -239,7 +239,6 @@ instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
|
||||
instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
|
||||
@ -35,8 +35,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
|
||||
#define SUPPORTS_NATIVE_CX8
|
||||
|
||||
#define SUPPORT_MONITOR_COUNT
|
||||
|
||||
// Aarch64 was not originally defined to be multi-copy-atomic, but now
|
||||
// is. See: "Simplifying ARM Concurrency: Multicopy-atomic Axiomatic
|
||||
// and Operational Models for ARMv8"
|
||||
|
||||
@ -1704,3 +1704,14 @@ void InterpreterMacroAssembler::load_method_entry(Register cache, Register index
|
||||
add(cache, cache, Array<ResolvedMethodEntry>::base_offset_in_bytes());
|
||||
lea(cache, Address(cache, index));
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void InterpreterMacroAssembler::verify_field_offset(Register reg) {
|
||||
// Verify the field offset is not in the header, implicitly checks for 0
|
||||
Label L;
|
||||
subs(zr, reg, oopDesc::base_offset_in_bytes());
|
||||
br(Assembler::GE, L);
|
||||
stop("bad field offset");
|
||||
bind(L);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -319,6 +319,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
void load_resolved_indy_entry(Register cache, Register index);
|
||||
void load_field_entry(Register cache, Register index, int bcp_offset = 1);
|
||||
void load_method_entry(Register cache, Register index, int bcp_offset = 1);
|
||||
|
||||
void verify_field_offset(Register reg) NOT_DEBUG_RETURN;
|
||||
};
|
||||
|
||||
#endif // CPU_AARCH64_INTERP_MASM_AARCH64_HPP
|
||||
|
||||
@ -39,24 +39,22 @@ public:
|
||||
// 3 - restoring an old state (javaCalls)
|
||||
|
||||
void clear(void) {
|
||||
// No hardware barriers are necessary. All members are volatile and the profiler
|
||||
// is run from a signal handler and only observers the thread its running on.
|
||||
|
||||
// clearing _last_Java_sp must be first
|
||||
_last_Java_sp = nullptr;
|
||||
OrderAccess::release();
|
||||
_last_Java_fp = nullptr;
|
||||
_last_Java_pc = nullptr;
|
||||
}
|
||||
|
||||
void copy(JavaFrameAnchor* src) {
|
||||
// In order to make sure the transition state is valid for "this"
|
||||
// No hardware barriers are necessary. All members are volatile and the profiler
|
||||
// is run from a signal handler and only observers the thread its running on.
|
||||
|
||||
// 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 = nullptr;
|
||||
OrderAccess::release();
|
||||
}
|
||||
_last_Java_fp = src->_last_Java_fp;
|
||||
_last_Java_pc = src->_last_Java_pc;
|
||||
|
||||
@ -148,56 +148,34 @@ extern "C" void disnm(intptr_t p);
|
||||
// strictly should be 64 bit movz #imm16<<0
|
||||
// 110___10100 (i.e. requires insn[31:21] == 11010010100)
|
||||
//
|
||||
class RelocActions {
|
||||
protected:
|
||||
typedef int (*reloc_insn)(address insn_addr, address &target);
|
||||
|
||||
virtual reloc_insn adrpMem() = 0;
|
||||
virtual reloc_insn adrpAdd() = 0;
|
||||
virtual reloc_insn adrpMovk() = 0;
|
||||
static uint32_t insn_at(address insn_addr, int n) {
|
||||
return ((uint32_t*)insn_addr)[n];
|
||||
}
|
||||
|
||||
const address _insn_addr;
|
||||
const uint32_t _insn;
|
||||
|
||||
static uint32_t insn_at(address insn_addr, int n) {
|
||||
return ((uint32_t*)insn_addr)[n];
|
||||
}
|
||||
uint32_t insn_at(int n) const {
|
||||
return insn_at(_insn_addr, n);
|
||||
}
|
||||
template<typename T>
|
||||
class RelocActions : public AllStatic {
|
||||
|
||||
public:
|
||||
|
||||
RelocActions(address insn_addr) : _insn_addr(insn_addr), _insn(insn_at(insn_addr, 0)) {}
|
||||
RelocActions(address insn_addr, uint32_t insn)
|
||||
: _insn_addr(insn_addr), _insn(insn) {}
|
||||
|
||||
virtual int unconditionalBranch(address insn_addr, address &target) = 0;
|
||||
virtual int conditionalBranch(address insn_addr, address &target) = 0;
|
||||
virtual int testAndBranch(address insn_addr, address &target) = 0;
|
||||
virtual int loadStore(address insn_addr, address &target) = 0;
|
||||
virtual int adr(address insn_addr, address &target) = 0;
|
||||
virtual int adrp(address insn_addr, address &target, reloc_insn inner) = 0;
|
||||
virtual int immediate(address insn_addr, address &target) = 0;
|
||||
virtual void verify(address insn_addr, address &target) = 0;
|
||||
|
||||
int ALWAYSINLINE run(address insn_addr, address &target) {
|
||||
static int ALWAYSINLINE run(address insn_addr, address &target) {
|
||||
int instructions = 1;
|
||||
uint32_t insn = insn_at(insn_addr, 0);
|
||||
|
||||
uint32_t dispatch = Instruction_aarch64::extract(_insn, 30, 25);
|
||||
uint32_t dispatch = Instruction_aarch64::extract(insn, 30, 25);
|
||||
switch(dispatch) {
|
||||
case 0b001010:
|
||||
case 0b001011: {
|
||||
instructions = unconditionalBranch(insn_addr, target);
|
||||
instructions = T::unconditionalBranch(insn_addr, target);
|
||||
break;
|
||||
}
|
||||
case 0b101010: // Conditional branch (immediate)
|
||||
case 0b011010: { // Compare & branch (immediate)
|
||||
instructions = conditionalBranch(insn_addr, target);
|
||||
break;
|
||||
instructions = T::conditionalBranch(insn_addr, target);
|
||||
break;
|
||||
}
|
||||
case 0b011011: {
|
||||
instructions = testAndBranch(insn_addr, target);
|
||||
instructions = T::testAndBranch(insn_addr, target);
|
||||
break;
|
||||
}
|
||||
case 0b001100:
|
||||
@ -209,9 +187,9 @@ public:
|
||||
case 0b111100:
|
||||
case 0b111110: {
|
||||
// load/store
|
||||
if ((Instruction_aarch64::extract(_insn, 29, 24) & 0b111011) == 0b011000) {
|
||||
if ((Instruction_aarch64::extract(insn, 29, 24) & 0b111011) == 0b011000) {
|
||||
// Load register (literal)
|
||||
instructions = loadStore(insn_addr, target);
|
||||
instructions = T::loadStore(insn_addr, target);
|
||||
break;
|
||||
} else {
|
||||
// nothing to do
|
||||
@ -224,27 +202,27 @@ public:
|
||||
case 0b101000:
|
||||
case 0b111000: {
|
||||
// adr/adrp
|
||||
assert(Instruction_aarch64::extract(_insn, 28, 24) == 0b10000, "must be");
|
||||
int shift = Instruction_aarch64::extract(_insn, 31, 31);
|
||||
assert(Instruction_aarch64::extract(insn, 28, 24) == 0b10000, "must be");
|
||||
int shift = Instruction_aarch64::extract(insn, 31, 31);
|
||||
if (shift) {
|
||||
uint32_t insn2 = insn_at(1);
|
||||
uint32_t insn2 = insn_at(insn_addr, 1);
|
||||
if (Instruction_aarch64::extract(insn2, 29, 24) == 0b111001 &&
|
||||
Instruction_aarch64::extract(_insn, 4, 0) ==
|
||||
Instruction_aarch64::extract(insn, 4, 0) ==
|
||||
Instruction_aarch64::extract(insn2, 9, 5)) {
|
||||
instructions = adrp(insn_addr, target, adrpMem());
|
||||
instructions = T::adrp(insn_addr, target, T::adrpMem);
|
||||
} else if (Instruction_aarch64::extract(insn2, 31, 22) == 0b1001000100 &&
|
||||
Instruction_aarch64::extract(_insn, 4, 0) ==
|
||||
Instruction_aarch64::extract(insn, 4, 0) ==
|
||||
Instruction_aarch64::extract(insn2, 4, 0)) {
|
||||
instructions = adrp(insn_addr, target, adrpAdd());
|
||||
instructions = T::adrp(insn_addr, target, T::adrpAdd);
|
||||
} else if (Instruction_aarch64::extract(insn2, 31, 21) == 0b11110010110 &&
|
||||
Instruction_aarch64::extract(_insn, 4, 0) ==
|
||||
Instruction_aarch64::extract(insn, 4, 0) ==
|
||||
Instruction_aarch64::extract(insn2, 4, 0)) {
|
||||
instructions = adrp(insn_addr, target, adrpMovk());
|
||||
instructions = T::adrp(insn_addr, target, T::adrpMovk);
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
} else {
|
||||
instructions = adr(insn_addr, target);
|
||||
instructions = T::adr(insn_addr, target);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -252,7 +230,7 @@ public:
|
||||
case 0b011001:
|
||||
case 0b101001:
|
||||
case 0b111001: {
|
||||
instructions = immediate(insn_addr, target);
|
||||
instructions = T::immediate(insn_addr, target);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -260,42 +238,36 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
verify(insn_addr, target);
|
||||
T::verify(insn_addr, target);
|
||||
return instructions * NativeInstruction::instruction_size;
|
||||
}
|
||||
};
|
||||
|
||||
class Patcher : public RelocActions {
|
||||
virtual reloc_insn adrpMem() { return &Patcher::adrpMem_impl; }
|
||||
virtual reloc_insn adrpAdd() { return &Patcher::adrpAdd_impl; }
|
||||
virtual reloc_insn adrpMovk() { return &Patcher::adrpMovk_impl; }
|
||||
|
||||
class Patcher : public AllStatic {
|
||||
public:
|
||||
Patcher(address insn_addr) : RelocActions(insn_addr) {}
|
||||
|
||||
virtual int unconditionalBranch(address insn_addr, address &target) {
|
||||
static int unconditionalBranch(address insn_addr, address &target) {
|
||||
intptr_t offset = (target - insn_addr) >> 2;
|
||||
Instruction_aarch64::spatch(insn_addr, 25, 0, offset);
|
||||
return 1;
|
||||
}
|
||||
virtual int conditionalBranch(address insn_addr, address &target) {
|
||||
static int conditionalBranch(address insn_addr, address &target) {
|
||||
intptr_t offset = (target - insn_addr) >> 2;
|
||||
Instruction_aarch64::spatch(insn_addr, 23, 5, offset);
|
||||
return 1;
|
||||
}
|
||||
virtual int testAndBranch(address insn_addr, address &target) {
|
||||
static int testAndBranch(address insn_addr, address &target) {
|
||||
intptr_t offset = (target - insn_addr) >> 2;
|
||||
Instruction_aarch64::spatch(insn_addr, 18, 5, offset);
|
||||
return 1;
|
||||
}
|
||||
virtual int loadStore(address insn_addr, address &target) {
|
||||
static int loadStore(address insn_addr, address &target) {
|
||||
intptr_t offset = (target - insn_addr) >> 2;
|
||||
Instruction_aarch64::spatch(insn_addr, 23, 5, offset);
|
||||
return 1;
|
||||
}
|
||||
virtual int adr(address insn_addr, address &target) {
|
||||
static int adr(address insn_addr, address &target) {
|
||||
#ifdef ASSERT
|
||||
assert(Instruction_aarch64::extract(_insn, 28, 24) == 0b10000, "must be");
|
||||
assert(Instruction_aarch64::extract(insn_at(insn_addr, 0), 28, 24) == 0b10000, "must be");
|
||||
#endif
|
||||
// PC-rel. addressing
|
||||
ptrdiff_t offset = target - insn_addr;
|
||||
@ -305,17 +277,18 @@ public:
|
||||
Instruction_aarch64::patch(insn_addr, 30, 29, offset_lo);
|
||||
return 1;
|
||||
}
|
||||
virtual int adrp(address insn_addr, address &target, reloc_insn inner) {
|
||||
template<typename U>
|
||||
static int adrp(address insn_addr, address &target, U inner) {
|
||||
int instructions = 1;
|
||||
#ifdef ASSERT
|
||||
assert(Instruction_aarch64::extract(_insn, 28, 24) == 0b10000, "must be");
|
||||
assert(Instruction_aarch64::extract(insn_at(insn_addr, 0), 28, 24) == 0b10000, "must be");
|
||||
#endif
|
||||
ptrdiff_t offset = target - insn_addr;
|
||||
instructions = 2;
|
||||
precond(inner != nullptr);
|
||||
// Give the inner reloc a chance to modify the target.
|
||||
address adjusted_target = target;
|
||||
instructions = (*inner)(insn_addr, adjusted_target);
|
||||
instructions = inner(insn_addr, adjusted_target);
|
||||
uintptr_t pc_page = (uintptr_t)insn_addr >> 12;
|
||||
uintptr_t adr_page = (uintptr_t)adjusted_target >> 12;
|
||||
offset = adr_page - pc_page;
|
||||
@ -325,7 +298,7 @@ public:
|
||||
Instruction_aarch64::patch(insn_addr, 30, 29, offset_lo);
|
||||
return instructions;
|
||||
}
|
||||
static int adrpMem_impl(address insn_addr, address &target) {
|
||||
static int adrpMem(address insn_addr, address &target) {
|
||||
uintptr_t dest = (uintptr_t)target;
|
||||
int offset_lo = dest & 0xfff;
|
||||
uint32_t insn2 = insn_at(insn_addr, 1);
|
||||
@ -334,21 +307,21 @@ public:
|
||||
guarantee(((dest >> size) << size) == dest, "misaligned target");
|
||||
return 2;
|
||||
}
|
||||
static int adrpAdd_impl(address insn_addr, address &target) {
|
||||
static int adrpAdd(address insn_addr, address &target) {
|
||||
uintptr_t dest = (uintptr_t)target;
|
||||
int offset_lo = dest & 0xfff;
|
||||
Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo);
|
||||
return 2;
|
||||
}
|
||||
static int adrpMovk_impl(address insn_addr, address &target) {
|
||||
static int adrpMovk(address insn_addr, address &target) {
|
||||
uintptr_t dest = uintptr_t(target);
|
||||
Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 20, 5, (uintptr_t)target >> 32);
|
||||
dest = (dest & 0xffffffffULL) | (uintptr_t(insn_addr) & 0xffff00000000ULL);
|
||||
target = address(dest);
|
||||
return 2;
|
||||
}
|
||||
virtual int immediate(address insn_addr, address &target) {
|
||||
assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
|
||||
static int immediate(address insn_addr, address &target) {
|
||||
assert(Instruction_aarch64::extract(insn_at(insn_addr, 0), 31, 21) == 0b11010010100, "must be");
|
||||
uint64_t dest = (uint64_t)target;
|
||||
// Move wide constant
|
||||
assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
|
||||
@ -358,7 +331,7 @@ public:
|
||||
Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
|
||||
return 3;
|
||||
}
|
||||
virtual void verify(address insn_addr, address &target) {
|
||||
static void verify(address insn_addr, address &target) {
|
||||
#ifdef ASSERT
|
||||
address address_is = MacroAssembler::target_addr_for_insn(insn_addr);
|
||||
if (!(address_is == target)) {
|
||||
@ -392,56 +365,54 @@ static bool offset_for(uint32_t insn1, uint32_t insn2, ptrdiff_t &byte_offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
class AArch64Decoder : public RelocActions {
|
||||
virtual reloc_insn adrpMem() { return &AArch64Decoder::adrpMem_impl; }
|
||||
virtual reloc_insn adrpAdd() { return &AArch64Decoder::adrpAdd_impl; }
|
||||
virtual reloc_insn adrpMovk() { return &AArch64Decoder::adrpMovk_impl; }
|
||||
|
||||
class AArch64Decoder : public AllStatic {
|
||||
public:
|
||||
AArch64Decoder(address insn_addr, uint32_t insn) : RelocActions(insn_addr, insn) {}
|
||||
|
||||
virtual int loadStore(address insn_addr, address &target) {
|
||||
intptr_t offset = Instruction_aarch64::sextract(_insn, 23, 5);
|
||||
static int loadStore(address insn_addr, address &target) {
|
||||
intptr_t offset = Instruction_aarch64::sextract(insn_at(insn_addr, 0), 23, 5);
|
||||
target = insn_addr + (offset << 2);
|
||||
return 1;
|
||||
}
|
||||
virtual int unconditionalBranch(address insn_addr, address &target) {
|
||||
intptr_t offset = Instruction_aarch64::sextract(_insn, 25, 0);
|
||||
static int unconditionalBranch(address insn_addr, address &target) {
|
||||
intptr_t offset = Instruction_aarch64::sextract(insn_at(insn_addr, 0), 25, 0);
|
||||
target = insn_addr + (offset << 2);
|
||||
return 1;
|
||||
}
|
||||
virtual int conditionalBranch(address insn_addr, address &target) {
|
||||
intptr_t offset = Instruction_aarch64::sextract(_insn, 23, 5);
|
||||
static int conditionalBranch(address insn_addr, address &target) {
|
||||
intptr_t offset = Instruction_aarch64::sextract(insn_at(insn_addr, 0), 23, 5);
|
||||
target = address(((uint64_t)insn_addr + (offset << 2)));
|
||||
return 1;
|
||||
}
|
||||
virtual int testAndBranch(address insn_addr, address &target) {
|
||||
intptr_t offset = Instruction_aarch64::sextract(_insn, 18, 5);
|
||||
static int testAndBranch(address insn_addr, address &target) {
|
||||
intptr_t offset = Instruction_aarch64::sextract(insn_at(insn_addr, 0), 18, 5);
|
||||
target = address(((uint64_t)insn_addr + (offset << 2)));
|
||||
return 1;
|
||||
}
|
||||
virtual int adr(address insn_addr, address &target) {
|
||||
static int adr(address insn_addr, address &target) {
|
||||
// PC-rel. addressing
|
||||
intptr_t offset = Instruction_aarch64::extract(_insn, 30, 29);
|
||||
offset |= Instruction_aarch64::sextract(_insn, 23, 5) << 2;
|
||||
uint32_t insn = insn_at(insn_addr, 0);
|
||||
intptr_t offset = Instruction_aarch64::extract(insn, 30, 29);
|
||||
offset |= Instruction_aarch64::sextract(insn, 23, 5) << 2;
|
||||
target = address((uint64_t)insn_addr + offset);
|
||||
return 1;
|
||||
}
|
||||
virtual int adrp(address insn_addr, address &target, reloc_insn inner) {
|
||||
assert(Instruction_aarch64::extract(_insn, 28, 24) == 0b10000, "must be");
|
||||
intptr_t offset = Instruction_aarch64::extract(_insn, 30, 29);
|
||||
offset |= Instruction_aarch64::sextract(_insn, 23, 5) << 2;
|
||||
template<typename U>
|
||||
static int adrp(address insn_addr, address &target, U inner) {
|
||||
uint32_t insn = insn_at(insn_addr, 0);
|
||||
assert(Instruction_aarch64::extract(insn, 28, 24) == 0b10000, "must be");
|
||||
intptr_t offset = Instruction_aarch64::extract(insn, 30, 29);
|
||||
offset |= Instruction_aarch64::sextract(insn, 23, 5) << 2;
|
||||
int shift = 12;
|
||||
offset <<= shift;
|
||||
uint64_t target_page = ((uint64_t)insn_addr) + offset;
|
||||
target_page &= ((uint64_t)-1) << shift;
|
||||
uint32_t insn2 = insn_at(1);
|
||||
uint32_t insn2 = insn_at(insn_addr, 1);
|
||||
target = address(target_page);
|
||||
precond(inner != nullptr);
|
||||
(*inner)(insn_addr, target);
|
||||
inner(insn_addr, target);
|
||||
return 2;
|
||||
}
|
||||
static int adrpMem_impl(address insn_addr, address &target) {
|
||||
static int adrpMem(address insn_addr, address &target) {
|
||||
uint32_t insn2 = insn_at(insn_addr, 1);
|
||||
// Load/store register (unsigned immediate)
|
||||
ptrdiff_t byte_offset = Instruction_aarch64::extract(insn2, 21, 10);
|
||||
@ -450,14 +421,14 @@ public:
|
||||
target += byte_offset;
|
||||
return 2;
|
||||
}
|
||||
static int adrpAdd_impl(address insn_addr, address &target) {
|
||||
static int adrpAdd(address insn_addr, address &target) {
|
||||
uint32_t insn2 = insn_at(insn_addr, 1);
|
||||
// add (immediate)
|
||||
ptrdiff_t byte_offset = Instruction_aarch64::extract(insn2, 21, 10);
|
||||
target += byte_offset;
|
||||
return 2;
|
||||
}
|
||||
static int adrpMovk_impl(address insn_addr, address &target) {
|
||||
static int adrpMovk(address insn_addr, address &target) {
|
||||
uint32_t insn2 = insn_at(insn_addr, 1);
|
||||
uint64_t dest = uint64_t(target);
|
||||
dest = (dest & 0xffff0000ffffffff) |
|
||||
@ -476,35 +447,33 @@ public:
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
virtual int immediate(address insn_addr, address &target) {
|
||||
static int immediate(address insn_addr, address &target) {
|
||||
uint32_t *insns = (uint32_t *)insn_addr;
|
||||
assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
|
||||
assert(Instruction_aarch64::extract(insns[0], 31, 21) == 0b11010010100, "must be");
|
||||
// Move wide constant: movz, movk, movk. See movptr().
|
||||
assert(nativeInstruction_at(insns+1)->is_movk(), "wrong insns in patch");
|
||||
assert(nativeInstruction_at(insns+2)->is_movk(), "wrong insns in patch");
|
||||
target = address(uint64_t(Instruction_aarch64::extract(_insn, 20, 5))
|
||||
+ (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16)
|
||||
+ (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32));
|
||||
target = address(uint64_t(Instruction_aarch64::extract(insns[0], 20, 5))
|
||||
+ (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16)
|
||||
+ (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32));
|
||||
assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
|
||||
assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
|
||||
return 3;
|
||||
}
|
||||
virtual void verify(address insn_addr, address &target) {
|
||||
static void verify(address insn_addr, address &target) {
|
||||
}
|
||||
};
|
||||
|
||||
address MacroAssembler::target_addr_for_insn(address insn_addr, uint32_t insn) {
|
||||
AArch64Decoder decoder(insn_addr, insn);
|
||||
address MacroAssembler::target_addr_for_insn(address insn_addr) {
|
||||
address target;
|
||||
decoder.run(insn_addr, target);
|
||||
RelocActions<AArch64Decoder>::run(insn_addr, target);
|
||||
return target;
|
||||
}
|
||||
|
||||
// Patch any kind of instruction; there may be several instructions.
|
||||
// Return the total length (in bytes) of the instructions.
|
||||
int MacroAssembler::pd_patch_instruction_size(address insn_addr, address target) {
|
||||
Patcher patcher(insn_addr);
|
||||
return patcher.run(insn_addr, target);
|
||||
return RelocActions<Patcher>::run(insn_addr, target);
|
||||
}
|
||||
|
||||
int MacroAssembler::patch_oop(address insn_addr, address o) {
|
||||
@ -546,11 +515,11 @@ int MacroAssembler::patch_narrow_klass(address insn_addr, narrowKlass n) {
|
||||
return 2 * NativeInstruction::instruction_size;
|
||||
}
|
||||
|
||||
address MacroAssembler::target_addr_for_insn_or_null(address insn_addr, unsigned insn) {
|
||||
if (NativeInstruction::is_ldrw_to_zr(address(&insn))) {
|
||||
address MacroAssembler::target_addr_for_insn_or_null(address insn_addr) {
|
||||
if (NativeInstruction::is_ldrw_to_zr(insn_addr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return MacroAssembler::target_addr_for_insn(insn_addr, insn);
|
||||
return MacroAssembler::target_addr_for_insn(insn_addr);
|
||||
}
|
||||
|
||||
void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool in_nmethod, Register tmp) {
|
||||
@ -634,12 +603,13 @@ void MacroAssembler::set_last_Java_frame(Register last_java_sp,
|
||||
last_java_sp = esp;
|
||||
}
|
||||
|
||||
str(last_java_sp, Address(rthread, JavaThread::last_Java_sp_offset()));
|
||||
|
||||
// last_java_fp is optional
|
||||
if (last_java_fp->is_valid()) {
|
||||
str(last_java_fp, Address(rthread, JavaThread::last_Java_fp_offset()));
|
||||
}
|
||||
|
||||
// We must set sp last.
|
||||
str(last_java_sp, Address(rthread, JavaThread::last_Java_sp_offset()));
|
||||
}
|
||||
|
||||
void MacroAssembler::set_last_Java_frame(Register last_java_sp,
|
||||
@ -5630,38 +5600,6 @@ void MacroAssembler::tlab_allocate(Register obj,
|
||||
bs->tlab_allocate(this, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
|
||||
}
|
||||
|
||||
void MacroAssembler::inc_held_monitor_count(Register tmp) {
|
||||
Address dst(rthread, JavaThread::held_monitor_count_offset());
|
||||
#ifdef ASSERT
|
||||
ldr(tmp, dst);
|
||||
increment(tmp);
|
||||
str(tmp, dst);
|
||||
Label ok;
|
||||
tbz(tmp, 63, ok);
|
||||
STOP("assert(held monitor count underflow)");
|
||||
should_not_reach_here();
|
||||
bind(ok);
|
||||
#else
|
||||
increment(dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MacroAssembler::dec_held_monitor_count(Register tmp) {
|
||||
Address dst(rthread, JavaThread::held_monitor_count_offset());
|
||||
#ifdef ASSERT
|
||||
ldr(tmp, dst);
|
||||
decrement(tmp);
|
||||
str(tmp, dst);
|
||||
Label ok;
|
||||
tbz(tmp, 63, ok);
|
||||
STOP("assert(held monitor count underflow)");
|
||||
should_not_reach_here();
|
||||
bind(ok);
|
||||
#else
|
||||
decrement(dst);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MacroAssembler::verify_tlab() {
|
||||
#ifdef ASSERT
|
||||
if (UseTLAB && VerifyOops) {
|
||||
|
||||
@ -676,16 +676,8 @@ public:
|
||||
static bool needs_explicit_null_check(intptr_t offset);
|
||||
static bool uses_implicit_null_check(void* address);
|
||||
|
||||
static address target_addr_for_insn(address insn_addr, unsigned insn);
|
||||
static address target_addr_for_insn_or_null(address insn_addr, unsigned insn);
|
||||
static address target_addr_for_insn(address insn_addr) {
|
||||
unsigned insn = *(unsigned*)insn_addr;
|
||||
return target_addr_for_insn(insn_addr, insn);
|
||||
}
|
||||
static address target_addr_for_insn_or_null(address insn_addr) {
|
||||
unsigned insn = *(unsigned*)insn_addr;
|
||||
return target_addr_for_insn_or_null(insn_addr, insn);
|
||||
}
|
||||
static address target_addr_for_insn(address insn_addr);
|
||||
static address target_addr_for_insn_or_null(address insn_addr);
|
||||
|
||||
// Required platform-specific helpers for Label::patch_instructions.
|
||||
// They _shadow_ the declarations in AbstractAssembler, which are undefined.
|
||||
@ -983,9 +975,6 @@ public:
|
||||
void push_cont_fastpath(Register java_thread = rthread);
|
||||
void pop_cont_fastpath(Register java_thread = rthread);
|
||||
|
||||
void inc_held_monitor_count(Register tmp);
|
||||
void dec_held_monitor_count(Register tmp);
|
||||
|
||||
// Round up to a power of two
|
||||
void round_to(Register reg, int modulus);
|
||||
|
||||
@ -1623,7 +1612,7 @@ public:
|
||||
FloatRegister p, FloatRegister z, FloatRegister t1);
|
||||
void ghash_reduce_wide(int index, FloatRegister result, FloatRegister lo, FloatRegister hi,
|
||||
FloatRegister p, FloatRegister z, FloatRegister t1);
|
||||
void ghash_processBlocks_wide(address p, Register state, Register subkeyH,
|
||||
void ghash_processBlocks_wide(Label& p, Register state, Register subkeyH,
|
||||
Register data, Register blocks, int unrolls);
|
||||
|
||||
|
||||
|
||||
@ -507,7 +507,7 @@ void MacroAssembler::ghash_modmul(FloatRegister result,
|
||||
//
|
||||
// Clobbers all vector registers.
|
||||
//
|
||||
void MacroAssembler::ghash_processBlocks_wide(address field_polynomial, Register state,
|
||||
void MacroAssembler::ghash_processBlocks_wide(Label& field_polynomial, Register state,
|
||||
Register subkeyH,
|
||||
Register data, Register blocks, int unrolls) {
|
||||
int register_stride = 7;
|
||||
@ -531,7 +531,10 @@ void MacroAssembler::ghash_processBlocks_wide(address field_polynomial, Register
|
||||
FloatRegister p = v31;
|
||||
eor(vzr, T16B, vzr, vzr); // zero register
|
||||
|
||||
ldrq(p, field_polynomial); // The field polynomial
|
||||
// load polynomial via label which must identify local data in the
|
||||
// same code stub
|
||||
adr(rscratch1, field_polynomial);
|
||||
ldrq(p, rscratch1); // The field polynomial
|
||||
|
||||
ldrq(v0, Address(state));
|
||||
ldrq(Hprime, Address(subkeyH));
|
||||
|
||||
@ -90,7 +90,6 @@ void Relocation::pd_set_call_destination(address x) {
|
||||
|
||||
void trampoline_stub_Relocation::pd_fix_owner_after_move() {
|
||||
NativeCall* call = nativeCall_at(owner());
|
||||
assert(call->raw_destination() == owner(), "destination should be empty");
|
||||
address trampoline = addr();
|
||||
address dest = nativeCallTrampolineStub_at(trampoline)->destination();
|
||||
if (!Assembler::reachable_from_branch_at(owner(), dest)) {
|
||||
|
||||
@ -683,12 +683,12 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
|
||||
int comp_args_on_stack,
|
||||
const BasicType *sig_bt,
|
||||
const VMRegPair *regs,
|
||||
AdapterHandlerEntry* handler) {
|
||||
address i2c_entry = __ pc();
|
||||
address entry_address[AdapterBlob::ENTRY_COUNT]) {
|
||||
entry_address[AdapterBlob::I2C] = __ pc();
|
||||
|
||||
gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs);
|
||||
|
||||
address c2i_unverified_entry = __ pc();
|
||||
entry_address[AdapterBlob::C2I_Unverified] = __ pc();
|
||||
Label skip_fixup;
|
||||
|
||||
Register data = rscratch2;
|
||||
@ -718,10 +718,10 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
|
||||
__ block_comment("} c2i_unverified_entry");
|
||||
}
|
||||
|
||||
address c2i_entry = __ pc();
|
||||
entry_address[AdapterBlob::C2I] = __ pc();
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
address c2i_no_clinit_check_entry = nullptr;
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr;
|
||||
if (VM_Version::supports_fast_class_init_checks()) {
|
||||
Label L_skip_barrier;
|
||||
|
||||
@ -736,15 +736,13 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
|
||||
__ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
|
||||
|
||||
__ bind(L_skip_barrier);
|
||||
c2i_no_clinit_check_entry = __ pc();
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
}
|
||||
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->c2i_entry_barrier(masm);
|
||||
|
||||
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
|
||||
|
||||
handler->set_entry_points(i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -987,11 +985,8 @@ static void fill_continuation_entry(MacroAssembler* masm) {
|
||||
|
||||
__ ldr(rscratch1, Address(rthread, JavaThread::cont_fastpath_offset()));
|
||||
__ str(rscratch1, Address(sp, ContinuationEntry::parent_cont_fastpath_offset()));
|
||||
__ ldr(rscratch1, Address(rthread, JavaThread::held_monitor_count_offset()));
|
||||
__ str(rscratch1, Address(sp, ContinuationEntry::parent_held_monitor_count_offset()));
|
||||
|
||||
__ str(zr, Address(rthread, JavaThread::cont_fastpath_offset()));
|
||||
__ str(zr, Address(rthread, JavaThread::held_monitor_count_offset()));
|
||||
}
|
||||
|
||||
// on entry, sp points to the ContinuationEntry
|
||||
@ -1007,50 +1002,6 @@ static void continuation_enter_cleanup(MacroAssembler* masm) {
|
||||
#endif
|
||||
__ ldr(rscratch1, Address(sp, ContinuationEntry::parent_cont_fastpath_offset()));
|
||||
__ str(rscratch1, Address(rthread, JavaThread::cont_fastpath_offset()));
|
||||
|
||||
if (CheckJNICalls) {
|
||||
// Check if this is a virtual thread continuation
|
||||
Label L_skip_vthread_code;
|
||||
__ ldrw(rscratch1, Address(sp, ContinuationEntry::flags_offset()));
|
||||
__ cbzw(rscratch1, L_skip_vthread_code);
|
||||
|
||||
// If the held monitor count is > 0 and this vthread is terminating then
|
||||
// it failed to release a JNI monitor. So we issue the same log message
|
||||
// that JavaThread::exit does.
|
||||
__ ldr(rscratch1, Address(rthread, JavaThread::jni_monitor_count_offset()));
|
||||
__ cbz(rscratch1, L_skip_vthread_code);
|
||||
|
||||
// Save return value potentially containing the exception oop in callee-saved R19.
|
||||
__ mov(r19, r0);
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::log_jni_monitor_still_held));
|
||||
// Restore potential return value.
|
||||
__ mov(r0, r19);
|
||||
|
||||
// For vthreads we have to explicitly zero the JNI monitor count of the carrier
|
||||
// on termination. The held count is implicitly zeroed below when we restore from
|
||||
// the parent held count (which has to be zero).
|
||||
__ str(zr, Address(rthread, JavaThread::jni_monitor_count_offset()));
|
||||
|
||||
__ bind(L_skip_vthread_code);
|
||||
}
|
||||
#ifdef ASSERT
|
||||
else {
|
||||
// Check if this is a virtual thread continuation
|
||||
Label L_skip_vthread_code;
|
||||
__ ldrw(rscratch1, Address(sp, ContinuationEntry::flags_offset()));
|
||||
__ cbzw(rscratch1, L_skip_vthread_code);
|
||||
|
||||
// See comment just above. If not checking JNI calls the JNI count is only
|
||||
// needed for assertion checking.
|
||||
__ str(zr, Address(rthread, JavaThread::jni_monitor_count_offset()));
|
||||
|
||||
__ bind(L_skip_vthread_code);
|
||||
}
|
||||
#endif
|
||||
|
||||
__ ldr(rscratch1, Address(sp, ContinuationEntry::parent_held_monitor_count_offset()));
|
||||
__ str(rscratch1, Address(rthread, JavaThread::held_monitor_count_offset()));
|
||||
|
||||
__ ldr(rscratch2, Address(sp, ContinuationEntry::parent_offset()));
|
||||
__ str(rscratch2, Address(rthread, JavaThread::cont_entry_offset()));
|
||||
__ add(rfp, sp, (int)ContinuationEntry::size());
|
||||
@ -1763,9 +1714,6 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
Label lock_done;
|
||||
|
||||
if (method->is_synchronized()) {
|
||||
Label count;
|
||||
const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes();
|
||||
|
||||
// Get the handle (the 2nd argument)
|
||||
__ mov(oop_handle_reg, c_rarg1);
|
||||
|
||||
|
||||
@ -802,7 +802,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
//
|
||||
// s and d are adjusted to point to the remaining words to copy
|
||||
//
|
||||
void generate_copy_longs(StubId stub_id, DecoratorSet decorators, Label &start, Register s, Register d, Register count) {
|
||||
address generate_copy_longs(StubId stub_id, DecoratorSet decorators, Register s, Register d, Register count) {
|
||||
BasicType type;
|
||||
copy_direction direction;
|
||||
|
||||
@ -854,7 +854,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
StubCodeMark mark(this, stub_id);
|
||||
|
||||
__ bind(start);
|
||||
address start = __ pc();
|
||||
|
||||
Label unaligned_copy_long;
|
||||
if (AvoidUnalignedAccesses) {
|
||||
@ -894,9 +894,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
int prefetch = PrefetchCopyIntervalInBytes;
|
||||
bool use_stride = false;
|
||||
if (direction == copy_backwards) {
|
||||
use_stride = prefetch > 256;
|
||||
prefetch = -prefetch;
|
||||
if (use_stride) __ mov(stride, prefetch);
|
||||
use_stride = prefetch > 256;
|
||||
prefetch = -prefetch;
|
||||
if (use_stride) __ mov(stride, prefetch);
|
||||
}
|
||||
|
||||
__ bind(again);
|
||||
@ -1026,9 +1026,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
int prefetch = PrefetchCopyIntervalInBytes;
|
||||
bool use_stride = false;
|
||||
if (direction == copy_backwards) {
|
||||
use_stride = prefetch > 256;
|
||||
prefetch = -prefetch;
|
||||
if (use_stride) __ mov(stride, prefetch);
|
||||
use_stride = prefetch > 256;
|
||||
prefetch = -prefetch;
|
||||
if (use_stride) __ mov(stride, prefetch);
|
||||
}
|
||||
|
||||
__ bind(again);
|
||||
@ -1037,15 +1037,15 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ prfm(use_stride ? Address(s, stride) : Address(s, prefetch), PLDL1KEEP);
|
||||
|
||||
if (direction == copy_forwards) {
|
||||
// allowing for the offset of -8 the store instructions place
|
||||
// registers into the target 64 bit block at the following
|
||||
// offsets
|
||||
//
|
||||
// t0 at offset 0
|
||||
// t1 at offset 8, t2 at offset 16
|
||||
// t3 at offset 24, t4 at offset 32
|
||||
// t5 at offset 40, t6 at offset 48
|
||||
// t7 at offset 56
|
||||
// allowing for the offset of -8 the store instructions place
|
||||
// registers into the target 64 bit block at the following
|
||||
// offsets
|
||||
//
|
||||
// t0 at offset 0
|
||||
// t1 at offset 8, t2 at offset 16
|
||||
// t3 at offset 24, t4 at offset 32
|
||||
// t5 at offset 40, t6 at offset 48
|
||||
// t7 at offset 56
|
||||
|
||||
bs.copy_store_at_8(Address(d, 1 * unit), t0);
|
||||
bs.copy_store_at_16(Address(d, 2 * unit), t1, t2);
|
||||
@ -1057,18 +1057,18 @@ class StubGenerator: public StubCodeGenerator {
|
||||
bs.copy_store_at_8(Address(__ pre(d, 8 * unit)), t7);
|
||||
bs.copy_load_at_16(t6, t7, Address(__ pre(s, 8 * unit)));
|
||||
} else {
|
||||
// d was not offset when we started so the registers are
|
||||
// written into the 64 bit block preceding d with the following
|
||||
// offsets
|
||||
//
|
||||
// t1 at offset -8
|
||||
// t3 at offset -24, t0 at offset -16
|
||||
// t5 at offset -48, t2 at offset -32
|
||||
// t7 at offset -56, t4 at offset -48
|
||||
// t6 at offset -64
|
||||
//
|
||||
// note that this matches the offsets previously noted for the
|
||||
// loads
|
||||
// d was not offset when we started so the registers are
|
||||
// written into the 64 bit block preceding d with the following
|
||||
// offsets
|
||||
//
|
||||
// t1 at offset -8
|
||||
// t3 at offset -24, t0 at offset -16
|
||||
// t5 at offset -48, t2 at offset -32
|
||||
// t7 at offset -56, t4 at offset -48
|
||||
// t6 at offset -64
|
||||
//
|
||||
// note that this matches the offsets previously noted for the
|
||||
// loads
|
||||
|
||||
bs.copy_store_at_8(Address(d, 1 * unit), t1);
|
||||
bs.copy_store_at_16(Address(d, 3 * unit), t3, t0);
|
||||
@ -1109,10 +1109,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
{
|
||||
Label L1, L2;
|
||||
__ tbz(count, exact_log2(4), L1);
|
||||
// this is the same as above but copying only 4 longs hence
|
||||
// with only one intervening stp between the str instructions
|
||||
// but note that the offsets and registers still follow the
|
||||
// same pattern
|
||||
// this is the same as above but copying only 4 longs hence
|
||||
// with only one intervening stp between the str instructions
|
||||
// but note that the offsets and registers still follow the
|
||||
// same pattern
|
||||
bs.copy_load_at_16(t0, t1, Address(s, 2 * unit));
|
||||
bs.copy_load_at_16(t2, t3, Address(__ pre(s, 4 * unit)));
|
||||
if (direction == copy_forwards) {
|
||||
@ -1127,10 +1127,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ bind(L1);
|
||||
|
||||
__ tbz(count, 1, L2);
|
||||
// this is the same as above but copying only 2 longs hence
|
||||
// there is no intervening stp between the str instructions
|
||||
// but note that the offset and register patterns are still
|
||||
// the same
|
||||
// this is the same as above but copying only 2 longs hence
|
||||
// there is no intervening stp between the str instructions
|
||||
// but note that the offset and register patterns are still
|
||||
// the same
|
||||
bs.copy_load_at_16(t0, t1, Address(__ pre(s, 2 * unit)));
|
||||
if (direction == copy_forwards) {
|
||||
bs.copy_store_at_8(Address(d, 1 * unit), t0);
|
||||
@ -1141,18 +1141,20 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
__ bind(L2);
|
||||
|
||||
// for forwards copy we need to re-adjust the offsets we
|
||||
// applied so that s and d are follow the last words written
|
||||
// for forwards copy we need to re-adjust the offsets we
|
||||
// applied so that s and d are follow the last words written
|
||||
|
||||
if (direction == copy_forwards) {
|
||||
__ add(s, s, 16);
|
||||
__ add(d, d, 8);
|
||||
}
|
||||
if (direction == copy_forwards) {
|
||||
__ add(s, s, 16);
|
||||
__ add(d, d, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
__ ret(lr);
|
||||
}
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Small copy: less than 16 bytes.
|
||||
@ -1206,10 +1208,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
Label copy_f, copy_b;
|
||||
Label copy_obj_f, copy_obj_b;
|
||||
Label copy_obj_uninit_f, copy_obj_uninit_b;
|
||||
|
||||
// All-singing all-dancing memory copy.
|
||||
//
|
||||
// Copy count units of memory from s to d. The size of a unit is
|
||||
@ -1447,19 +1445,19 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
if (direction == copy_forwards) {
|
||||
if (type != T_OBJECT) {
|
||||
__ bl(copy_f);
|
||||
__ bl(StubRoutines::aarch64::copy_byte_f());
|
||||
} else if ((decorators & IS_DEST_UNINITIALIZED) != 0) {
|
||||
__ bl(copy_obj_uninit_f);
|
||||
__ bl(StubRoutines::aarch64::copy_oop_uninit_f());
|
||||
} else {
|
||||
__ bl(copy_obj_f);
|
||||
__ bl(StubRoutines::aarch64::copy_oop_f());
|
||||
}
|
||||
} else {
|
||||
if (type != T_OBJECT) {
|
||||
__ bl(copy_b);
|
||||
__ bl(StubRoutines::aarch64::copy_byte_b());
|
||||
} else if ((decorators & IS_DEST_UNINITIALIZED) != 0) {
|
||||
__ bl(copy_obj_uninit_b);
|
||||
__ bl(StubRoutines::aarch64::copy_oop_uninit_b());
|
||||
} else {
|
||||
__ bl(copy_obj_b);
|
||||
__ bl(StubRoutines::aarch64::copy_oop_b());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1522,11 +1520,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// the hardware handle it. The two dwords within qwords that span
|
||||
// cache line boundaries will still be loaded and stored atomically.
|
||||
//
|
||||
// Side Effects: entry is set to the (post push) entry point so it
|
||||
// can be used by the corresponding conjoint copy
|
||||
// method
|
||||
// Side Effects: nopush_entry is set to the (post push) entry point
|
||||
// so it can be used by the corresponding conjoint
|
||||
// copy method
|
||||
//
|
||||
address generate_disjoint_copy(StubId stub_id, address *entry) {
|
||||
address generate_disjoint_copy(StubId stub_id, address *nopush_entry) {
|
||||
Register s = c_rarg0, d = c_rarg1, count = c_rarg2;
|
||||
RegSet saved_reg = RegSet::of(s, d, count);
|
||||
int size;
|
||||
@ -1615,8 +1613,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
address start = __ pc();
|
||||
__ enter();
|
||||
|
||||
if (entry != nullptr) {
|
||||
*entry = __ pc();
|
||||
if (nopush_entry != nullptr) {
|
||||
*nopush_entry = __ pc();
|
||||
// caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
|
||||
BLOCK_COMMENT("Entry:");
|
||||
}
|
||||
@ -1679,10 +1677,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// cache line boundaries will still be loaded and stored atomically.
|
||||
//
|
||||
// Side Effects:
|
||||
// entry is set to the no-overlap entry point so it can be used by
|
||||
// some other conjoint copy method
|
||||
// nopush_entry is set to the no-overlap entry point so it can be
|
||||
// used by some other conjoint copy method
|
||||
//
|
||||
address generate_conjoint_copy(StubId stub_id, address nooverlap_target, address *entry) {
|
||||
address generate_conjoint_copy(StubId stub_id, address nooverlap_target, address *nopush_entry) {
|
||||
Register s = c_rarg0, d = c_rarg1, count = c_rarg2;
|
||||
RegSet saved_regs = RegSet::of(s, d, count);
|
||||
int size;
|
||||
@ -1769,16 +1767,19 @@ class StubGenerator: public StubCodeGenerator {
|
||||
address start = __ pc();
|
||||
__ enter();
|
||||
|
||||
if (entry != nullptr) {
|
||||
*entry = __ pc();
|
||||
if (nopush_entry != nullptr) {
|
||||
*nopush_entry = __ pc();
|
||||
// caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
|
||||
BLOCK_COMMENT("Entry:");
|
||||
}
|
||||
|
||||
// use fwd copy when (d-s) above_equal (count*size)
|
||||
Label L_overlapping;
|
||||
__ sub(rscratch1, d, s);
|
||||
__ cmp(rscratch1, count, Assembler::LSL, exact_log2(size));
|
||||
__ br(Assembler::HS, nooverlap_target);
|
||||
__ br(Assembler::LO, L_overlapping);
|
||||
__ b(RuntimeAddress(nooverlap_target));
|
||||
__ bind(L_overlapping);
|
||||
|
||||
DecoratorSet decorators = IN_HEAP | IS_ARRAY;
|
||||
if (dest_uninitialized) {
|
||||
@ -1850,7 +1851,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// r0 == 0 - success
|
||||
// r0 == -1^K - failure, where K is partial transfer count
|
||||
//
|
||||
address generate_checkcast_copy(StubId stub_id, address *entry) {
|
||||
address generate_checkcast_copy(StubId stub_id, address *nopush_entry) {
|
||||
bool dest_uninitialized;
|
||||
switch (stub_id) {
|
||||
case StubId::stubgen_checkcast_arraycopy_id:
|
||||
@ -1911,8 +1912,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
#endif //ASSERT
|
||||
|
||||
// Caller of this entry point must set up the argument registers.
|
||||
if (entry != nullptr) {
|
||||
*entry = __ pc();
|
||||
if (nopush_entry != nullptr) {
|
||||
*nopush_entry = __ pc();
|
||||
BLOCK_COMMENT("Entry:");
|
||||
}
|
||||
|
||||
@ -2724,13 +2725,21 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
|
||||
void generate_arraycopy_stubs() {
|
||||
address entry;
|
||||
address entry_jbyte_arraycopy;
|
||||
address entry_jshort_arraycopy;
|
||||
address entry_jint_arraycopy;
|
||||
address entry_oop_arraycopy;
|
||||
address entry_jlong_arraycopy;
|
||||
address entry_checkcast_arraycopy;
|
||||
// Some copy stubs publish a normal entry and then a 2nd 'fallback'
|
||||
// entry immediately following their stack push. This can be used
|
||||
// as a post-push branch target for compatible stubs when they
|
||||
// identify a special case that can be handled by the fallback
|
||||
// stub e.g a disjoint copy stub may be use as a special case
|
||||
// fallback for its compatible conjoint copy stub.
|
||||
//
|
||||
// A no push entry is always returned in the following local and
|
||||
// then published by assigning to the appropriate entry field in
|
||||
// class StubRoutines. The entry value is then passed to the
|
||||
// generator for the compatible stub. That means the entry must be
|
||||
// listed when saving to/restoring from the AOT cache, ensuring
|
||||
// that the inter-stub jumps are noted at AOT-cache save and
|
||||
// relocated at AOT cache load.
|
||||
address nopush_entry;
|
||||
|
||||
// generate the common exit first so later stubs can rely on it if
|
||||
// they want an UnsafeMemoryAccess exit non-local to the stub
|
||||
@ -2738,83 +2747,123 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// register the stub as the default exit with class UnsafeMemoryAccess
|
||||
UnsafeMemoryAccess::set_common_exit_stub_pc(StubRoutines::_unsafecopy_common_exit);
|
||||
|
||||
generate_copy_longs(StubId::stubgen_copy_byte_f_id, IN_HEAP | IS_ARRAY, copy_f, r0, r1, r15);
|
||||
generate_copy_longs(StubId::stubgen_copy_byte_b_id, IN_HEAP | IS_ARRAY, copy_b, r0, r1, r15);
|
||||
// generate and publish arch64-specific bulk copy routines first
|
||||
// so we can call them from other copy stubs
|
||||
StubRoutines::aarch64::_copy_byte_f = generate_copy_longs(StubId::stubgen_copy_byte_f_id, IN_HEAP | IS_ARRAY, r0, r1, r15);
|
||||
StubRoutines::aarch64::_copy_byte_b = generate_copy_longs(StubId::stubgen_copy_byte_b_id, IN_HEAP | IS_ARRAY, r0, r1, r15);
|
||||
|
||||
generate_copy_longs(StubId::stubgen_copy_oop_f_id, IN_HEAP | IS_ARRAY, copy_obj_f, r0, r1, r15);
|
||||
generate_copy_longs(StubId::stubgen_copy_oop_b_id, IN_HEAP | IS_ARRAY, copy_obj_b, r0, r1, r15);
|
||||
StubRoutines::aarch64::_copy_oop_f = generate_copy_longs(StubId::stubgen_copy_oop_f_id, IN_HEAP | IS_ARRAY, r0, r1, r15);
|
||||
StubRoutines::aarch64::_copy_oop_b = generate_copy_longs(StubId::stubgen_copy_oop_b_id, IN_HEAP | IS_ARRAY, r0, r1, r15);
|
||||
|
||||
generate_copy_longs(StubId::stubgen_copy_oop_uninit_f_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, copy_obj_uninit_f, r0, r1, r15);
|
||||
generate_copy_longs(StubId::stubgen_copy_oop_uninit_b_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, copy_obj_uninit_b, r0, r1, r15);
|
||||
StubRoutines::aarch64::_copy_oop_uninit_f = generate_copy_longs(StubId::stubgen_copy_oop_uninit_f_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, r0, r1, r15);
|
||||
StubRoutines::aarch64::_copy_oop_uninit_b = generate_copy_longs(StubId::stubgen_copy_oop_uninit_b_id, IN_HEAP | IS_ARRAY | IS_DEST_UNINITIALIZED, r0, r1, r15);
|
||||
|
||||
StubRoutines::aarch64::_zero_blocks = generate_zero_blocks();
|
||||
|
||||
//*** jbyte
|
||||
// Always need aligned and unaligned versions
|
||||
StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jbyte_disjoint_arraycopy_id, &entry);
|
||||
StubRoutines::_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_jbyte_arraycopy_id, entry, &entry_jbyte_arraycopy);
|
||||
StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jbyte_disjoint_arraycopy_id, &entry);
|
||||
StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jbyte_arraycopy_id, entry, nullptr);
|
||||
StubRoutines::_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jbyte_disjoint_arraycopy_id, &nopush_entry);
|
||||
// disjoint nopush entry is needed by conjoint copy
|
||||
StubRoutines::_jbyte_disjoint_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_jbyte_arraycopy_id, StubRoutines::_jbyte_disjoint_arraycopy_nopush, &nopush_entry);
|
||||
// conjoint nopush entry is needed by generic/unsafe copy
|
||||
StubRoutines::_jbyte_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_arrayof_jbyte_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jbyte_disjoint_arraycopy_id, &nopush_entry);
|
||||
// disjoint arrayof nopush entry is needed by conjoint copy
|
||||
StubRoutines::_arrayof_jbyte_disjoint_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_arrayof_jbyte_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jbyte_arraycopy_id, StubRoutines::_arrayof_jbyte_disjoint_arraycopy_nopush, nullptr);
|
||||
|
||||
//*** jshort
|
||||
// Always need aligned and unaligned versions
|
||||
StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jshort_disjoint_arraycopy_id, &entry);
|
||||
StubRoutines::_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_jshort_arraycopy_id, entry, &entry_jshort_arraycopy);
|
||||
StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jshort_disjoint_arraycopy_id, &entry);
|
||||
StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jshort_arraycopy_id, entry, nullptr);
|
||||
StubRoutines::_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jshort_disjoint_arraycopy_id, &nopush_entry);
|
||||
// disjoint nopush entry is needed by conjoint copy
|
||||
StubRoutines::_jshort_disjoint_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_jshort_arraycopy_id, StubRoutines::_jshort_disjoint_arraycopy_nopush, &nopush_entry);
|
||||
// conjoint nopush entry is used by generic/unsafe copy
|
||||
StubRoutines::_jshort_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_arrayof_jshort_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jshort_disjoint_arraycopy_id, &nopush_entry);
|
||||
// disjoint arrayof nopush entry is needed by conjoint copy
|
||||
StubRoutines::_arrayof_jshort_disjoint_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_arrayof_jshort_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jshort_arraycopy_id, StubRoutines::_arrayof_jshort_disjoint_arraycopy_nopush, nullptr);
|
||||
|
||||
//*** jint
|
||||
// Aligned versions
|
||||
StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jint_disjoint_arraycopy_id, &entry);
|
||||
StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jint_arraycopy_id, entry, &entry_jint_arraycopy);
|
||||
StubRoutines::_arrayof_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jint_disjoint_arraycopy_id, &nopush_entry);
|
||||
// disjoint arrayof nopush entry is needed by conjoint copy
|
||||
StubRoutines::_arrayof_jint_disjoint_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_arrayof_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jint_arraycopy_id, StubRoutines::_arrayof_jint_disjoint_arraycopy_nopush, nullptr);
|
||||
// In 64 bit we need both aligned and unaligned versions of jint arraycopy.
|
||||
// entry_jint_arraycopy always points to the unaligned version
|
||||
StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jint_disjoint_arraycopy_id, &entry);
|
||||
StubRoutines::_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_jint_arraycopy_id, entry, &entry_jint_arraycopy);
|
||||
// jint_arraycopy_nopush always points to the unaligned version
|
||||
StubRoutines::_jint_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_jint_disjoint_arraycopy_id, &nopush_entry);
|
||||
// disjoint nopush entry is needed by conjoint copy
|
||||
StubRoutines::_jint_disjoint_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_jint_arraycopy = generate_conjoint_copy(StubId::stubgen_jint_arraycopy_id, StubRoutines::_jint_disjoint_arraycopy_nopush, &nopush_entry);
|
||||
// conjoint nopush entry is needed by generic/unsafe copy
|
||||
StubRoutines::_jint_arraycopy_nopush = nopush_entry;
|
||||
|
||||
//*** jlong
|
||||
// It is always aligned
|
||||
StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jlong_disjoint_arraycopy_id, &entry);
|
||||
StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jlong_arraycopy_id, entry, &entry_jlong_arraycopy);
|
||||
StubRoutines::_arrayof_jlong_disjoint_arraycopy = generate_disjoint_copy(StubId::stubgen_arrayof_jlong_disjoint_arraycopy_id, &nopush_entry);
|
||||
// disjoint arrayof nopush entry is needed by conjoint copy
|
||||
StubRoutines::_arrayof_jlong_disjoint_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_arrayof_jlong_arraycopy = generate_conjoint_copy(StubId::stubgen_arrayof_jlong_arraycopy_id, StubRoutines::_arrayof_jlong_disjoint_arraycopy_nopush, &nopush_entry);
|
||||
// conjoint nopush entry is needed by generic/unsafe copy
|
||||
StubRoutines::_jlong_arraycopy_nopush = nopush_entry;
|
||||
// disjoint normal/nopush and conjoint normal entries are not
|
||||
// generated since the arrayof versions are the same
|
||||
StubRoutines::_jlong_disjoint_arraycopy = StubRoutines::_arrayof_jlong_disjoint_arraycopy;
|
||||
StubRoutines::_jlong_disjoint_arraycopy_nopush = StubRoutines::_arrayof_jlong_disjoint_arraycopy_nopush;
|
||||
StubRoutines::_jlong_arraycopy = StubRoutines::_arrayof_jlong_arraycopy;
|
||||
|
||||
//*** oops
|
||||
{
|
||||
// With compressed oops we need unaligned versions; notice that
|
||||
// we overwrite entry_oop_arraycopy.
|
||||
bool aligned = !UseCompressedOops;
|
||||
|
||||
StubRoutines::_arrayof_oop_disjoint_arraycopy
|
||||
= generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_id, &entry);
|
||||
= generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_id, &nopush_entry);
|
||||
// disjoint arrayof nopush entry is needed by conjoint copy
|
||||
StubRoutines::_arrayof_oop_disjoint_arraycopy_nopush = nopush_entry;
|
||||
StubRoutines::_arrayof_oop_arraycopy
|
||||
= generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_id, entry, &entry_oop_arraycopy);
|
||||
= generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_id, StubRoutines::_arrayof_oop_disjoint_arraycopy_nopush, &nopush_entry);
|
||||
// conjoint arrayof nopush entry is needed by generic/unsafe copy
|
||||
StubRoutines::_oop_arraycopy_nopush = nopush_entry;
|
||||
// Aligned versions without pre-barriers
|
||||
StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit
|
||||
= generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_uninit_id, &entry);
|
||||
= generate_disjoint_copy(StubId::stubgen_arrayof_oop_disjoint_arraycopy_uninit_id, &nopush_entry);
|
||||
// disjoint arrayof+uninit nopush entry is needed by conjoint copy
|
||||
StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit_nopush = nopush_entry;
|
||||
// note that we don't need a returned nopush entry because the
|
||||
// generic/unsafe copy does not cater for uninit arrays.
|
||||
StubRoutines::_arrayof_oop_arraycopy_uninit
|
||||
= generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_uninit_id, entry, nullptr);
|
||||
= generate_conjoint_copy(StubId::stubgen_arrayof_oop_arraycopy_uninit_id, StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit_nopush, nullptr);
|
||||
}
|
||||
|
||||
// for oop copies reuse arrayof entries for non-arrayof cases
|
||||
StubRoutines::_oop_disjoint_arraycopy = StubRoutines::_arrayof_oop_disjoint_arraycopy;
|
||||
StubRoutines::_oop_disjoint_arraycopy_nopush = StubRoutines::_arrayof_oop_disjoint_arraycopy_nopush;
|
||||
StubRoutines::_oop_arraycopy = StubRoutines::_arrayof_oop_arraycopy;
|
||||
StubRoutines::_oop_disjoint_arraycopy_uninit = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit;
|
||||
StubRoutines::_oop_disjoint_arraycopy_uninit_nopush = StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit_nopush;
|
||||
StubRoutines::_oop_arraycopy_uninit = StubRoutines::_arrayof_oop_arraycopy_uninit;
|
||||
|
||||
StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_id, &entry_checkcast_arraycopy);
|
||||
StubRoutines::_checkcast_arraycopy = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_id, &nopush_entry);
|
||||
// checkcast nopush entry is needed by generic copy
|
||||
StubRoutines::_checkcast_arraycopy_nopush = nopush_entry;
|
||||
// note that we don't need a returned nopush entry because the
|
||||
// generic copy does not cater for uninit arrays.
|
||||
StubRoutines::_checkcast_arraycopy_uninit = generate_checkcast_copy(StubId::stubgen_checkcast_arraycopy_uninit_id, nullptr);
|
||||
|
||||
StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(entry_jbyte_arraycopy,
|
||||
entry_jshort_arraycopy,
|
||||
entry_jint_arraycopy,
|
||||
entry_jlong_arraycopy);
|
||||
// unsafe arraycopy may fallback on conjoint stubs
|
||||
StubRoutines::_unsafe_arraycopy = generate_unsafe_copy(StubRoutines::_jbyte_arraycopy_nopush,
|
||||
StubRoutines::_jshort_arraycopy_nopush,
|
||||
StubRoutines::_jint_arraycopy_nopush,
|
||||
StubRoutines::_jlong_arraycopy_nopush);
|
||||
|
||||
StubRoutines::_generic_arraycopy = generate_generic_copy(entry_jbyte_arraycopy,
|
||||
entry_jshort_arraycopy,
|
||||
entry_jint_arraycopy,
|
||||
entry_oop_arraycopy,
|
||||
entry_jlong_arraycopy,
|
||||
entry_checkcast_arraycopy);
|
||||
// generic arraycopy may fallback on conjoint stubs
|
||||
StubRoutines::_generic_arraycopy = generate_generic_copy(StubRoutines::_jbyte_arraycopy_nopush,
|
||||
StubRoutines::_jshort_arraycopy_nopush,
|
||||
StubRoutines::_jint_arraycopy_nopush,
|
||||
StubRoutines::_oop_arraycopy_nopush,
|
||||
StubRoutines::_jlong_arraycopy_nopush,
|
||||
StubRoutines::_checkcast_arraycopy_nopush);
|
||||
|
||||
StubRoutines::_jbyte_fill = generate_fill(StubId::stubgen_jbyte_fill_id);
|
||||
StubRoutines::_jshort_fill = generate_fill(StubId::stubgen_jshort_fill_id);
|
||||
@ -3402,14 +3451,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// counter = c_rarg7 - 16 bytes of CTR
|
||||
// return - number of processed bytes
|
||||
address generate_galoisCounterMode_AESCrypt() {
|
||||
address ghash_polynomial = __ pc();
|
||||
__ emit_int64(0x87); // The low-order bits of the field
|
||||
// polynomial (i.e. p = z^7+z^2+z+1)
|
||||
// repeated in the low and high parts of a
|
||||
// 128-bit vector
|
||||
__ emit_int64(0x87);
|
||||
Label ghash_polynomial; // local data generated after code
|
||||
|
||||
__ align(CodeEntryAlignment);
|
||||
__ align(CodeEntryAlignment);
|
||||
StubId stub_id = StubId::stubgen_galoisCounterMode_AESCrypt_id;
|
||||
StubCodeMark mark(this, stub_id);
|
||||
address start = __ pc();
|
||||
@ -3514,7 +3558,17 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
__ leave(); // required for proper stackwalking of RuntimeStub frame
|
||||
__ ret(lr);
|
||||
return start;
|
||||
|
||||
// bind label and generate polynomial data
|
||||
__ align(wordSize * 2);
|
||||
__ bind(ghash_polynomial);
|
||||
__ emit_int64(0x87); // The low-order bits of the field
|
||||
// polynomial (i.e. p = z^7+z^2+z+1)
|
||||
// repeated in the low and high parts of a
|
||||
// 128-bit vector
|
||||
__ emit_int64(0x87);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
class Cached64Bytes {
|
||||
@ -4559,16 +4613,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// by the second lane from all vectors and so on.
|
||||
address generate_chacha20Block_blockpar() {
|
||||
Label L_twoRounds, L_cc20_const;
|
||||
// The constant data is broken into two 128-bit segments to be loaded
|
||||
// onto FloatRegisters. The first 128 bits are a counter add overlay
|
||||
// that adds +0/+1/+2/+3 to the vector holding replicated state[12].
|
||||
// The second 128-bits is a table constant used for 8-bit left rotations.
|
||||
__ BIND(L_cc20_const);
|
||||
__ emit_int64(0x0000000100000000UL);
|
||||
__ emit_int64(0x0000000300000002UL);
|
||||
__ emit_int64(0x0605040702010003UL);
|
||||
__ emit_int64(0x0E0D0C0F0A09080BUL);
|
||||
|
||||
__ align(CodeEntryAlignment);
|
||||
StubId stub_id = StubId::stubgen_chacha20Block_id;
|
||||
StubCodeMark mark(this, stub_id);
|
||||
@ -4716,6 +4760,17 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ leave();
|
||||
__ ret(lr);
|
||||
|
||||
// bind label and generate local constant data used by this stub
|
||||
// The constant data is broken into two 128-bit segments to be loaded
|
||||
// onto FloatRegisters. The first 128 bits are a counter add overlay
|
||||
// that adds +0/+1/+2/+3 to the vector holding replicated state[12].
|
||||
// The second 128-bits is a table constant used for 8-bit left rotations.
|
||||
__ BIND(L_cc20_const);
|
||||
__ emit_int64(0x0000000100000000UL);
|
||||
__ emit_int64(0x0000000300000002UL);
|
||||
__ emit_int64(0x0605040702010003UL);
|
||||
__ emit_int64(0x0E0D0C0F0A09080BUL);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
@ -6036,10 +6091,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
address generate_kyber12To16() {
|
||||
Label L_F00, L_loop, L_end;
|
||||
|
||||
__ BIND(L_F00);
|
||||
__ emit_int64(0x0f000f000f000f00);
|
||||
__ emit_int64(0x0f000f000f000f00);
|
||||
|
||||
__ align(CodeEntryAlignment);
|
||||
StubId stub_id = StubId::stubgen_kyber12To16_id;
|
||||
StubCodeMark mark(this, stub_id);
|
||||
@ -6233,6 +6284,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ mov(r0, zr); // return 0
|
||||
__ ret(lr);
|
||||
|
||||
// bind label and generate constant data used by this stub
|
||||
__ BIND(L_F00);
|
||||
__ emit_int64(0x0f000f000f000f00);
|
||||
__ emit_int64(0x0f000f000f000f00);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
@ -9642,14 +9698,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
StubId stub_id = StubId::stubgen_ghash_processBlocks_id;
|
||||
StubCodeMark mark(this, stub_id);
|
||||
__ align(wordSize * 2);
|
||||
address p = __ pc();
|
||||
__ emit_int64(0x87); // The low-order bits of the field
|
||||
// polynomial (i.e. p = z^7+z^2+z+1)
|
||||
// repeated in the low and high parts of a
|
||||
// 128-bit vector
|
||||
__ emit_int64(0x87);
|
||||
|
||||
Label polynomial; // local data generated at end of stub
|
||||
__ align(CodeEntryAlignment);
|
||||
address start = __ pc();
|
||||
|
||||
@ -9661,7 +9710,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
FloatRegister vzr = v30;
|
||||
__ eor(vzr, __ T16B, vzr, vzr); // zero register
|
||||
|
||||
__ ldrq(v24, p); // The field polynomial
|
||||
__ adr(rscratch1, polynomial);
|
||||
__ ldrq(v24, rscratch1); // The field polynomial
|
||||
|
||||
__ ldrq(v0, Address(state));
|
||||
__ ldrq(v1, Address(subkeyH));
|
||||
@ -9701,6 +9751,15 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ st1(v0, __ T16B, state);
|
||||
__ ret(lr);
|
||||
|
||||
// bind label and generate local polynomial data
|
||||
__ align(wordSize * 2);
|
||||
__ bind(polynomial);
|
||||
__ emit_int64(0x87); // The low-order bits of the field
|
||||
// polynomial (i.e. p = z^7+z^2+z+1)
|
||||
// repeated in the low and high parts of a
|
||||
// 128-bit vector
|
||||
__ emit_int64(0x87);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
@ -9709,14 +9768,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
StubId stub_id = StubId::stubgen_ghash_processBlocks_wide_id;
|
||||
StubCodeMark mark(this, stub_id);
|
||||
__ align(wordSize * 2);
|
||||
address p = __ pc();
|
||||
__ emit_int64(0x87); // The low-order bits of the field
|
||||
// polynomial (i.e. p = z^7+z^2+z+1)
|
||||
// repeated in the low and high parts of a
|
||||
// 128-bit vector
|
||||
__ emit_int64(0x87);
|
||||
|
||||
Label polynomial; // local data generated after stub
|
||||
__ align(CodeEntryAlignment);
|
||||
address start = __ pc();
|
||||
|
||||
@ -9738,7 +9790,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ st1(v8, v9, v10, v11, __ T16B, Address(sp));
|
||||
}
|
||||
|
||||
__ ghash_processBlocks_wide(p, state, subkeyH, data, blocks, unroll);
|
||||
__ ghash_processBlocks_wide(polynomial, state, subkeyH, data, blocks, unroll);
|
||||
|
||||
if (unroll > 1) {
|
||||
// And restore state
|
||||
@ -9751,7 +9803,17 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
__ ret(lr);
|
||||
|
||||
// bind label and generate polynomial data
|
||||
__ align(wordSize * 2);
|
||||
__ bind(polynomial);
|
||||
__ emit_int64(0x87); // The low-order bits of the field
|
||||
// polynomial (i.e. p = z^7+z^2+z+1)
|
||||
// repeated in the low and high parts of a
|
||||
// 128-bit vector
|
||||
__ emit_int64(0x87);
|
||||
|
||||
return start;
|
||||
|
||||
}
|
||||
|
||||
void generate_base64_encode_simdround(Register src, Register dst,
|
||||
|
||||
@ -168,6 +168,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
|
||||
Register temp_reg, bool load_bc_into_bc_reg/*=true*/,
|
||||
int byte_no)
|
||||
{
|
||||
assert_different_registers(bc_reg, temp_reg);
|
||||
if (!RewriteBytecodes) return;
|
||||
Label L_patch_done;
|
||||
|
||||
@ -231,9 +232,12 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
|
||||
__ stop("patching the wrong bytecode");
|
||||
__ bind(L_okay);
|
||||
#endif
|
||||
|
||||
// patch bytecode
|
||||
__ strb(bc_reg, at_bcp(0));
|
||||
// Patch bytecode with release store to coordinate with ResolvedFieldEntry loads
|
||||
// in fast bytecode codelets. load_field_entry has a memory barrier that gains
|
||||
// the needed ordering, together with control dependency on entering the fast codelet
|
||||
// itself.
|
||||
__ lea(temp_reg, at_bcp(0));
|
||||
__ stlrb(bc_reg, temp_reg);
|
||||
__ bind(L_patch_done);
|
||||
}
|
||||
|
||||
@ -2269,7 +2273,7 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no,
|
||||
assert_different_registers(Rcache, index, temp);
|
||||
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
|
||||
|
||||
Label resolved, clinit_barrier_slow;
|
||||
Label L_clinit_barrier_slow, L_done;
|
||||
|
||||
Bytecodes::Code code = bytecode();
|
||||
__ load_method_entry(Rcache, index);
|
||||
@ -2284,11 +2288,20 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no,
|
||||
// Load-acquire the bytecode to match store-release in InterpreterRuntime
|
||||
__ ldarb(temp, temp);
|
||||
__ subs(zr, temp, (int) code); // have we resolved this bytecode?
|
||||
__ br(Assembler::EQ, resolved);
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
|
||||
__ br(Assembler::NE, L_clinit_barrier_slow);
|
||||
__ ldr(temp, Address(Rcache, in_bytes(ResolvedMethodEntry::method_offset())));
|
||||
__ load_method_holder(temp, temp);
|
||||
__ clinit_barrier(temp, rscratch1, &L_done, /*L_slow_path*/ nullptr);
|
||||
__ bind(L_clinit_barrier_slow);
|
||||
} else {
|
||||
__ br(Assembler::EQ, L_done);
|
||||
}
|
||||
|
||||
// resolve first time through
|
||||
// Class initialization barrier slow path lands here as well.
|
||||
__ bind(clinit_barrier_slow);
|
||||
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
|
||||
__ mov(temp, (int) code);
|
||||
__ call_VM(noreg, entry, temp);
|
||||
@ -2297,14 +2310,7 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no,
|
||||
__ load_method_entry(Rcache, index);
|
||||
// n.b. unlike x86 Rcache is now rcpool plus the indexed offset
|
||||
// so all clients ofthis method must be modified accordingly
|
||||
__ bind(resolved);
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
|
||||
__ ldr(temp, Address(Rcache, in_bytes(ResolvedMethodEntry::method_offset())));
|
||||
__ load_method_holder(temp, temp);
|
||||
__ clinit_barrier(temp, rscratch1, nullptr, &clinit_barrier_slow);
|
||||
}
|
||||
__ bind(L_done);
|
||||
}
|
||||
|
||||
void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
|
||||
@ -2313,7 +2319,7 @@ void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
|
||||
const Register temp = r19;
|
||||
assert_different_registers(Rcache, index, temp);
|
||||
|
||||
Label resolved;
|
||||
Label L_clinit_barrier_slow, L_done;
|
||||
|
||||
Bytecodes::Code code = bytecode();
|
||||
switch (code) {
|
||||
@ -2332,16 +2338,29 @@ void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
|
||||
// Load-acquire the bytecode to match store-release in ResolvedFieldEntry::fill_in()
|
||||
__ ldarb(temp, temp);
|
||||
__ subs(zr, temp, (int) code); // have we resolved this bytecode?
|
||||
__ br(Assembler::EQ, resolved);
|
||||
|
||||
// Class initialization barrier for static fields
|
||||
if (VM_Version::supports_fast_class_init_checks() &&
|
||||
(bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic)) {
|
||||
const Register field_holder = temp;
|
||||
|
||||
__ br(Assembler::NE, L_clinit_barrier_slow);
|
||||
__ ldr(field_holder, Address(Rcache, in_bytes(ResolvedFieldEntry::field_holder_offset())));
|
||||
__ clinit_barrier(field_holder, rscratch1, &L_done, /*L_slow_path*/ nullptr);
|
||||
__ bind(L_clinit_barrier_slow);
|
||||
} else {
|
||||
__ br(Assembler::EQ, L_done);
|
||||
}
|
||||
|
||||
// resolve first time through
|
||||
// Class initialization barrier slow path lands here as well.
|
||||
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
|
||||
__ mov(temp, (int) code);
|
||||
__ call_VM(noreg, entry, temp);
|
||||
|
||||
// Update registers with resolved info
|
||||
__ load_field_entry(Rcache, index);
|
||||
__ bind(resolved);
|
||||
__ bind(L_done);
|
||||
}
|
||||
|
||||
void TemplateTable::load_resolved_field_entry(Register obj,
|
||||
@ -3079,6 +3098,7 @@ void TemplateTable::fast_storefield(TosState state)
|
||||
|
||||
// R1: field offset, R2: field holder, R5: flags
|
||||
load_resolved_field_entry(r2, r2, noreg, r1, r5);
|
||||
__ verify_field_offset(r1);
|
||||
|
||||
{
|
||||
Label notVolatile;
|
||||
@ -3168,6 +3188,8 @@ void TemplateTable::fast_accessfield(TosState state)
|
||||
__ load_field_entry(r2, r1);
|
||||
|
||||
__ load_sized_value(r1, Address(r2, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(int), true /*is_signed*/);
|
||||
__ verify_field_offset(r1);
|
||||
|
||||
__ load_unsigned_byte(r3, Address(r2, in_bytes(ResolvedFieldEntry::flags_offset())));
|
||||
|
||||
// r0: object
|
||||
@ -3234,7 +3256,9 @@ void TemplateTable::fast_xaccess(TosState state)
|
||||
__ ldr(r0, aaddress(0));
|
||||
// access constant pool cache
|
||||
__ load_field_entry(r2, r3, 2);
|
||||
|
||||
__ load_sized_value(r1, Address(r2, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(int), true /*is_signed*/);
|
||||
__ verify_field_offset(r1);
|
||||
|
||||
// 8179954: We need to make sure that the code generated for
|
||||
// volatile accesses forms a sequentially-consistent set of
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright 2025 Arm Limited and/or its affiliates.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -222,10 +223,13 @@ void VM_Version::initialize() {
|
||||
// Neoverse
|
||||
// N1: 0xd0c
|
||||
// N2: 0xd49
|
||||
// N3: 0xd8e
|
||||
// V1: 0xd40
|
||||
// V2: 0xd4f
|
||||
// V3: 0xd84
|
||||
if (_cpu == CPU_ARM && (model_is(0xd0c) || model_is(0xd49) ||
|
||||
model_is(0xd40) || model_is(0xd4f))) {
|
||||
model_is(0xd40) || model_is(0xd4f) ||
|
||||
model_is(0xd8e) || model_is(0xd84))) {
|
||||
if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) {
|
||||
FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true);
|
||||
}
|
||||
@ -260,7 +264,9 @@ void VM_Version::initialize() {
|
||||
// Neoverse
|
||||
// V1: 0xd40
|
||||
// V2: 0xd4f
|
||||
if (_cpu == CPU_ARM && (model_is(0xd40) || model_is(0xd4f))) {
|
||||
// V3: 0xd84
|
||||
if (_cpu == CPU_ARM &&
|
||||
(model_is(0xd40) || model_is(0xd4f) || model_is(0xd84))) {
|
||||
if (FLAG_IS_DEFAULT(UseCryptoPmullForCRC32)) {
|
||||
FLAG_SET_DEFAULT(UseCryptoPmullForCRC32, true);
|
||||
}
|
||||
|
||||
@ -1131,31 +1131,27 @@ bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
|
||||
}
|
||||
|
||||
// Register for DIVI projection of divmodI
|
||||
RegMask Matcher::divI_proj_mask() {
|
||||
const RegMask& Matcher::divI_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask();
|
||||
return RegMask::EMPTY;
|
||||
}
|
||||
|
||||
// Register for MODI projection of divmodI
|
||||
RegMask Matcher::modI_proj_mask() {
|
||||
const RegMask& Matcher::modI_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask();
|
||||
return RegMask::EMPTY;
|
||||
}
|
||||
|
||||
// Register for DIVL projection of divmodL
|
||||
RegMask Matcher::divL_proj_mask() {
|
||||
const RegMask& Matcher::divL_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask();
|
||||
return RegMask::EMPTY;
|
||||
}
|
||||
|
||||
// Register for MODL projection of divmodL
|
||||
RegMask Matcher::modL_proj_mask() {
|
||||
const RegMask& Matcher::modL_proj_mask() {
|
||||
ShouldNotReachHere();
|
||||
return RegMask();
|
||||
}
|
||||
|
||||
const RegMask Matcher::method_handle_invoke_SP_save_mask() {
|
||||
return FP_REGP_mask();
|
||||
return RegMask::EMPTY;
|
||||
}
|
||||
|
||||
bool maybe_far_call(const CallNode *n) {
|
||||
@ -1248,23 +1244,6 @@ encode %{
|
||||
__ set_inst_mark(mark);
|
||||
%}
|
||||
|
||||
enc_class preserve_SP %{
|
||||
// preserve mark
|
||||
address mark = __ inst_mark();
|
||||
DEBUG_ONLY(int off0 = __ offset());
|
||||
// FP is preserved across all calls, even compiled calls.
|
||||
// Use it to preserve SP in places where the callee might change the SP.
|
||||
__ mov(Rmh_SP_save, SP);
|
||||
DEBUG_ONLY(int off1 = __ offset());
|
||||
assert(off1 - off0 == 4, "correct size prediction");
|
||||
// restore mark
|
||||
__ set_inst_mark(mark);
|
||||
%}
|
||||
|
||||
enc_class restore_SP %{
|
||||
__ mov(SP, Rmh_SP_save);
|
||||
%}
|
||||
|
||||
enc_class Java_Dynamic_Call (method meth) %{
|
||||
Register R8_ic_reg = reg_to_register_object(Matcher::inline_cache_reg_encode());
|
||||
assert(R8_ic_reg == Ricklass, "should be");
|
||||
@ -8799,7 +8778,6 @@ instruct safePoint_poll(iRegP poll, R12RegI tmp, flagsReg icc) %{
|
||||
// Call Java Static Instruction
|
||||
instruct CallStaticJavaDirect( method meth ) %{
|
||||
match(CallStaticJava);
|
||||
predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke());
|
||||
effect(USE meth);
|
||||
|
||||
ins_cost(CALL_COST);
|
||||
@ -8808,20 +8786,6 @@ instruct CallStaticJavaDirect( method meth ) %{
|
||||
ins_pipe(simple_call);
|
||||
%}
|
||||
|
||||
// Call Java Static Instruction (method handle version)
|
||||
instruct CallStaticJavaHandle( method meth ) %{
|
||||
match(CallStaticJava);
|
||||
predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
|
||||
effect(USE meth);
|
||||
// FP is saved by all callees (for interpreter stack correction).
|
||||
// We use it here for a similar purpose, in {preserve,restore}_FP.
|
||||
|
||||
ins_cost(CALL_COST);
|
||||
format %{ "CALL,static/MethodHandle ==> " %}
|
||||
ins_encode( SetInstMark, preserve_SP, Java_Static_Call( meth ), restore_SP, call_epilog, ClearInstMark );
|
||||
ins_pipe(simple_call);
|
||||
%}
|
||||
|
||||
// Call Java Dynamic Instruction
|
||||
instruct CallDynamicJavaDirect( method meth ) %{
|
||||
match(CallDynamicJava);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2008, 2025, 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
|
||||
@ -432,8 +432,7 @@ OptoRegPair c2::return_value(int ideal_reg) {
|
||||
|
||||
int MachCallStaticJavaNode::ret_addr_offset() {
|
||||
bool far = (_method == nullptr) ? maybe_far_call(this) : !cache_reachable();
|
||||
return ((far ? 3 : 1) + (_method_handle_invoke ? 1 : 0)) *
|
||||
NativeInstruction::instruction_size;
|
||||
return (far ? 3 : 1) * NativeInstruction::instruction_size;
|
||||
}
|
||||
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() {
|
||||
|
||||
@ -200,9 +200,10 @@ void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
|
||||
|
||||
void MonitorExitStub::emit_code(LIR_Assembler* ce) {
|
||||
__ bind(_entry);
|
||||
if (_compute_lock) {
|
||||
ce->monitor_address(_monitor_ix, _lock_reg);
|
||||
}
|
||||
|
||||
// lock_reg was destroyed by fast unlocking attempt => recompute it
|
||||
ce->monitor_address(_monitor_ix, _lock_reg);
|
||||
|
||||
const Register lock_reg = _lock_reg->as_pointer_register();
|
||||
|
||||
ce->verify_reserved_argument_area_size(1);
|
||||
|
||||
@ -174,11 +174,6 @@ 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;
|
||||
|
||||
@ -245,7 +245,7 @@ int LIR_Assembler::emit_unwind_handler() {
|
||||
MonitorExitStub* stub = nullptr;
|
||||
if (method()->is_synchronized()) {
|
||||
monitor_address(0, FrameMap::R0_opr);
|
||||
stub = new MonitorExitStub(FrameMap::R0_opr, true, 0);
|
||||
stub = new MonitorExitStub(FrameMap::R0_opr, 0);
|
||||
__ unlock_object(R2, R1, R0, *stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
@ -2427,7 +2427,6 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
|
||||
Register lock = op->lock_opr()->as_pointer_register();
|
||||
|
||||
if (op->code() == lir_lock) {
|
||||
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
|
||||
int null_check_offset = __ lock_object(hdr, obj, lock, *op->stub()->entry());
|
||||
if (op->info() != nullptr) {
|
||||
add_debug_info_for_null_check(null_check_offset, op->info());
|
||||
|
||||
@ -176,17 +176,17 @@ void C1_MacroAssembler::allocate_array(Register obj, Register len,
|
||||
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, Label& slow_case) {
|
||||
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register basic_lock, Label& slow_case) {
|
||||
int null_check_offset = 0;
|
||||
|
||||
const Register tmp2 = Rtemp; // Rtemp should be free at c1 LIR level
|
||||
assert_different_registers(hdr, obj, disp_hdr, tmp2);
|
||||
assert_different_registers(hdr, obj, basic_lock, tmp2);
|
||||
|
||||
assert(BasicObjectLock::lock_offset() == 0, "adjust this code");
|
||||
assert(oopDesc::mark_offset_in_bytes() == 0, "Required by atomic instructions");
|
||||
|
||||
// save object being locked into the BasicObjectLock
|
||||
str(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
|
||||
str(obj, Address(basic_lock, BasicObjectLock::obj_offset()));
|
||||
|
||||
null_check_offset = offset();
|
||||
|
||||
@ -197,26 +197,26 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
|
||||
b(slow_case, ne);
|
||||
}
|
||||
|
||||
Register t1 = disp_hdr; // Needs saving, probably
|
||||
Register t2 = hdr; // blow
|
||||
Register t3 = Rtemp; // blow
|
||||
Register t1 = basic_lock; // Needs saving, probably
|
||||
Register t2 = hdr; // blow
|
||||
Register t3 = Rtemp; // blow
|
||||
|
||||
lightweight_lock(obj, t1, t2, t3, 1 /* savemask - save t1 */, slow_case);
|
||||
// Success: fall through
|
||||
return null_check_offset;
|
||||
}
|
||||
|
||||
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
|
||||
assert_different_registers(hdr, obj, disp_hdr, Rtemp);
|
||||
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register basic_lock, Label& slow_case) {
|
||||
assert_different_registers(hdr, obj, basic_lock, Rtemp);
|
||||
|
||||
assert(BasicObjectLock::lock_offset() == 0, "adjust this code");
|
||||
assert(oopDesc::mark_offset_in_bytes() == 0, "Required by atomic instructions");
|
||||
|
||||
ldr(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
|
||||
ldr(obj, Address(basic_lock, BasicObjectLock::obj_offset()));
|
||||
|
||||
Register t1 = disp_hdr; // Needs saving, probably
|
||||
Register t2 = hdr; // blow
|
||||
Register t3 = Rtemp; // blow
|
||||
Register t1 = basic_lock; // Needs saving, probably
|
||||
Register t2 = hdr; // blow
|
||||
Register t3 = Rtemp; // blow
|
||||
|
||||
lightweight_unlock(obj, t1, t2, t3, 1 /* savemask - save t1 */, slow_case);
|
||||
// Success: fall through
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2025, 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
|
||||
@ -59,9 +59,9 @@
|
||||
max_array_allocation_length = 0x01000000
|
||||
};
|
||||
|
||||
int lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case);
|
||||
int lock_object(Register hdr, Register obj, Register basic_lock, Label& slow_case);
|
||||
|
||||
void unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case);
|
||||
void unlock_object(Register hdr, Register obj, Register basic_lock, Label& slow_case);
|
||||
|
||||
// This platform only uses signal-based null checks. The Label is not needed.
|
||||
void null_check(Register r, Label *Lnull = nullptr) { MacroAssembler::null_check(r); }
|
||||
|
||||
@ -275,14 +275,6 @@ OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address targe
|
||||
}
|
||||
|
||||
|
||||
static void restore_sp_for_method_handle(StubAssembler* sasm) {
|
||||
// Restore SP from its saved reg (FP) if the exception PC is a MethodHandle call site.
|
||||
__ ldr_s32(Rtemp, Address(Rthread, JavaThread::is_method_handle_return_offset()));
|
||||
__ cmp(Rtemp, 0);
|
||||
__ mov(SP, Rmh_SP_save, ne);
|
||||
}
|
||||
|
||||
|
||||
OopMapSet* Runtime1::generate_handle_exception(StubId id, StubAssembler* sasm) {
|
||||
__ block_comment("generate_handle_exception");
|
||||
|
||||
@ -339,7 +331,6 @@ OopMapSet* Runtime1::generate_handle_exception(StubId id, StubAssembler* sasm) {
|
||||
break;
|
||||
case StubId::c1_handle_exception_from_callee_id:
|
||||
restore_live_registers_without_return(sasm); // must not jump immediately to handler
|
||||
restore_sp_for_method_handle(sasm);
|
||||
__ ret();
|
||||
break;
|
||||
default: ShouldNotReachHere();
|
||||
@ -372,9 +363,6 @@ void Runtime1::generate_unwind_exception(StubAssembler* sasm) {
|
||||
// Jump to handler
|
||||
__ verify_not_null_oop(Rexception_obj);
|
||||
|
||||
// JSR292 extension
|
||||
restore_sp_for_method_handle(sasm);
|
||||
|
||||
__ jump(R0);
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +54,6 @@ define_pd_global(size_t, CodeCacheExpansionSize, 32*K );
|
||||
define_pd_global(size_t, CodeCacheMinBlockLength, 1);
|
||||
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
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);
|
||||
|
||||
@ -80,9 +80,6 @@ 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
|
||||
@ -91,8 +88,6 @@ 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(size_t, CodeCacheMinBlockLength, 6);
|
||||
define_pd_global(size_t, CodeCacheMinimumUseSpace, 400*K);
|
||||
|
||||
@ -329,56 +329,6 @@ JavaThread** frame::saved_thread_address(const frame& f) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 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(nmethod* 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_inclusive(original_pc),
|
||||
"original PC must be in the main code section of the compiled method (or must be immediately following it)");
|
||||
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:
|
||||
|
||||
nmethod* sender_nm = (_cb == nullptr) ? nullptr : _cb->as_nmethod_or_null();
|
||||
if (sender_nm != nullptr) {
|
||||
// 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_nm->is_deopt_mh_entry(_pc)) {
|
||||
DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, _fp));
|
||||
_unextended_sp = _fp;
|
||||
}
|
||||
else if (sender_nm->is_deopt_entry(_pc)) {
|
||||
DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp));
|
||||
}
|
||||
else if (sender_nm->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) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2025, 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
|
||||
@ -85,20 +85,11 @@
|
||||
// original sp.
|
||||
|
||||
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(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false);
|
||||
static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) {
|
||||
verify_deopt_original_pc(nm, unextended_sp, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2025, 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
|
||||
@ -112,8 +112,6 @@ inline void frame::init(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, add
|
||||
}
|
||||
|
||||
inline void frame::setup(address pc) {
|
||||
adjust_unextended_sp();
|
||||
|
||||
address original_pc = get_deopt_original_pc();
|
||||
if (original_pc != nullptr) {
|
||||
_pc = original_pc;
|
||||
|
||||
@ -198,15 +198,18 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
static void generate_post_barrier_fast_path(MacroAssembler* masm,
|
||||
const Register store_addr,
|
||||
const Register new_val,
|
||||
const Register tmp1,
|
||||
const Register tmp2,
|
||||
Label& done,
|
||||
bool new_val_may_be_null) {
|
||||
// Does store cross heap regions?
|
||||
static void generate_post_barrier(MacroAssembler* masm,
|
||||
const Register store_addr,
|
||||
const Register new_val,
|
||||
const Register thread,
|
||||
const Register tmp1,
|
||||
const Register tmp2,
|
||||
Label& done,
|
||||
bool new_val_may_be_null) {
|
||||
assert(thread == Rthread, "must be");
|
||||
assert_different_registers(store_addr, new_val, thread, tmp1, tmp2, noreg);
|
||||
|
||||
// Does store cross heap regions?
|
||||
__ eor(tmp1, store_addr, new_val);
|
||||
__ movs(tmp1, AsmOperand(tmp1, lsr, G1HeapRegion::LogOfHRGrainBytes));
|
||||
__ b(done, eq);
|
||||
@ -215,76 +218,34 @@ static void generate_post_barrier_fast_path(MacroAssembler* masm,
|
||||
if (new_val_may_be_null) {
|
||||
__ cbz(new_val, done);
|
||||
}
|
||||
// storing region crossing non-null, is card already dirty?
|
||||
const Register card_addr = tmp1;
|
||||
|
||||
CardTableBarrierSet* ct = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
|
||||
__ mov_address(tmp2, (address)ct->card_table()->byte_map_base());
|
||||
__ add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTable::card_shift()));
|
||||
// storing region crossing non-null, is card already non-clean?
|
||||
Address card_table_addr(thread, in_bytes(G1ThreadLocalData::card_table_base_offset()));
|
||||
__ ldr(tmp2, card_table_addr);
|
||||
__ add(tmp1, tmp2, AsmOperand(store_addr, lsr, CardTable::card_shift()));
|
||||
|
||||
__ ldrb(tmp2, Address(card_addr));
|
||||
__ cmp(tmp2, (int)G1CardTable::g1_young_card_val());
|
||||
if (UseCondCardMark) {
|
||||
__ ldrb(tmp2, Address(tmp1));
|
||||
// Instead of loading clean_card_val and comparing, we exploit the fact that
|
||||
// the LSB of non-clean cards is always 0, and the LSB of clean cards 1.
|
||||
__ tbz(tmp2, 0, done);
|
||||
}
|
||||
|
||||
static_assert(G1CardTable::dirty_card_val() == 0, "must be to use zero_register()");
|
||||
__ zero_register(tmp2);
|
||||
__ strb(tmp2, Address(tmp1)); // *(card address) := dirty_card_val
|
||||
}
|
||||
|
||||
static void generate_post_barrier_slow_path(MacroAssembler* masm,
|
||||
const Register thread,
|
||||
const Register tmp1,
|
||||
const Register tmp2,
|
||||
const Register tmp3,
|
||||
Label& done,
|
||||
Label& runtime) {
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2);
|
||||
assert(CardTable::dirty_card_val() == 0, "adjust this code");
|
||||
// card_addr is loaded by generate_post_barrier_fast_path
|
||||
const Register card_addr = tmp1;
|
||||
__ ldrb(tmp2, Address(card_addr));
|
||||
__ cbz(tmp2, done);
|
||||
|
||||
// storing a region crossing, non-null oop, card is clean.
|
||||
// dirty card and log.
|
||||
|
||||
__ strb(__ zero_register(tmp2), Address(card_addr));
|
||||
generate_queue_test_and_insertion(masm,
|
||||
G1ThreadLocalData::dirty_card_queue_index_offset(),
|
||||
G1ThreadLocalData::dirty_card_queue_buffer_offset(),
|
||||
runtime,
|
||||
thread, card_addr, tmp2, tmp3);
|
||||
__ b(done);
|
||||
}
|
||||
|
||||
|
||||
// G1 post-barrier.
|
||||
// Blows all volatile registers R0-R3, LR).
|
||||
void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register tmp1,
|
||||
Register tmp2,
|
||||
Register tmp3) {
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register tmp1,
|
||||
Register tmp2,
|
||||
Register tmp3) {
|
||||
Label done;
|
||||
Label runtime;
|
||||
|
||||
generate_post_barrier_fast_path(masm, store_addr, new_val, tmp1, tmp2, done, true /* new_val_may_be_null */);
|
||||
// If card is young, jump to done
|
||||
// card_addr and card are loaded by generate_post_barrier_fast_path
|
||||
const Register card = tmp2;
|
||||
const Register card_addr = tmp1;
|
||||
__ b(done, eq);
|
||||
generate_post_barrier_slow_path(masm, Rthread, card_addr, tmp2, tmp3, done, runtime);
|
||||
|
||||
__ bind(runtime);
|
||||
|
||||
RegisterSet set = RegisterSet(store_addr) | RegisterSet(R0, R3) | RegisterSet(R12);
|
||||
__ push(set);
|
||||
|
||||
if (card_addr != R0) {
|
||||
__ mov(R0, card_addr);
|
||||
}
|
||||
__ mov(R1, Rthread);
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), R0, R1);
|
||||
|
||||
__ pop(set);
|
||||
|
||||
generate_post_barrier(masm, store_addr, new_val, Rthread, tmp1, tmp2, done, true /* new_val_may_be_null */);
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
@ -344,35 +305,10 @@ void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm,
|
||||
Register tmp1,
|
||||
Register tmp2,
|
||||
Register tmp3,
|
||||
G1PostBarrierStubC2* stub) {
|
||||
assert(thread == Rthread, "must be");
|
||||
assert_different_registers(store_addr, new_val, thread, tmp1, tmp2, noreg);
|
||||
|
||||
stub->initialize_registers(thread, tmp1, tmp2, tmp3);
|
||||
|
||||
bool new_val_may_be_null = (stub->barrier_data() & G1C2BarrierPostNotNull) == 0;
|
||||
generate_post_barrier_fast_path(masm, store_addr, new_val, tmp1, tmp2, *stub->continuation(), new_val_may_be_null);
|
||||
// If card is not young, jump to stub (slow path)
|
||||
__ b(*stub->entry(), ne);
|
||||
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::generate_c2_post_barrier_stub(MacroAssembler* masm,
|
||||
G1PostBarrierStubC2* stub) const {
|
||||
Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
|
||||
Label runtime;
|
||||
Register thread = stub->thread();
|
||||
Register tmp1 = stub->tmp1(); // tmp1 holds the card address.
|
||||
Register tmp2 = stub->tmp2();
|
||||
Register tmp3 = stub->tmp3();
|
||||
|
||||
__ bind(*stub->entry());
|
||||
generate_post_barrier_slow_path(masm, thread, tmp1, tmp2, tmp3, *stub->continuation(), runtime);
|
||||
|
||||
__ bind(runtime);
|
||||
generate_c2_barrier_runtime_call(masm, stub, tmp1, CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), tmp2);
|
||||
__ b(*stub->continuation());
|
||||
bool new_val_may_be_null) {
|
||||
Label done;
|
||||
generate_post_barrier(masm, store_addr, new_val, thread, tmp1, tmp2, done, new_val_may_be_null);
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
#endif // COMPILER2
|
||||
@ -463,20 +399,19 @@ void G1BarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrier
|
||||
__ b(*stub->continuation());
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::gen_post_barrier_stub(LIR_Assembler* ce, G1PostBarrierStub* stub) {
|
||||
G1BarrierSetC1* bs = (G1BarrierSetC1*)BarrierSet::barrier_set()->barrier_set_c1();
|
||||
__ bind(*stub->entry());
|
||||
assert(stub->addr()->is_register(), "Precondition.");
|
||||
assert(stub->new_val()->is_register(), "Precondition.");
|
||||
Register new_val_reg = stub->new_val()->as_register();
|
||||
__ cbz(new_val_reg, *stub->continuation());
|
||||
ce->verify_reserved_argument_area_size(1);
|
||||
__ str(stub->addr()->as_pointer_register(), Address(SP));
|
||||
__ call(bs->post_barrier_c1_runtime_code_blob()->code_begin(), relocInfo::runtime_call_type);
|
||||
__ b(*stub->continuation());
|
||||
#undef __
|
||||
|
||||
void G1BarrierSetAssembler::g1_write_barrier_post_c1(MacroAssembler* masm,
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register thread,
|
||||
Register tmp1,
|
||||
Register tmp2) {
|
||||
Label done;
|
||||
generate_post_barrier(masm, store_addr, new_val, thread, tmp1, tmp2, done, true /* new_val_may_be_null */);
|
||||
masm->bind(done);
|
||||
}
|
||||
|
||||
#undef __
|
||||
#define __ sasm->
|
||||
|
||||
void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm) {
|
||||
@ -536,102 +471,6 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler*
|
||||
__ b(done);
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* sasm) {
|
||||
// Input:
|
||||
// - store_addr, pushed on the stack
|
||||
|
||||
__ set_info("g1_post_barrier_slow_id", false);
|
||||
|
||||
Label done;
|
||||
Label recheck;
|
||||
Label runtime;
|
||||
|
||||
Address queue_index(Rthread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
|
||||
Address buffer(Rthread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
|
||||
|
||||
AddressLiteral cardtable(ci_card_table_address_as<address>(), relocInfo::none);
|
||||
|
||||
// save at least the registers that need saving if the runtime is called
|
||||
const RegisterSet saved_regs = RegisterSet(R0,R3) | RegisterSet(R12) | RegisterSet(LR);
|
||||
const int nb_saved_regs = 6;
|
||||
assert(nb_saved_regs == saved_regs.size(), "fix nb_saved_regs");
|
||||
__ push(saved_regs);
|
||||
|
||||
const Register r_card_addr_0 = R0; // must be R0 for the slow case
|
||||
const Register r_obj_0 = R0;
|
||||
const Register r_card_base_1 = R1;
|
||||
const Register r_tmp2 = R2;
|
||||
const Register r_index_2 = R2;
|
||||
const Register r_buffer_3 = R3;
|
||||
const Register tmp1 = Rtemp;
|
||||
|
||||
__ ldr(r_obj_0, Address(SP, nb_saved_regs*wordSize));
|
||||
// Note: there is a comment in x86 code about not using
|
||||
// ExternalAddress / lea, due to relocation not working
|
||||
// properly for that address. Should be OK for arm, where we
|
||||
// explicitly specify that 'cardtable' has a relocInfo::none
|
||||
// type.
|
||||
__ lea(r_card_base_1, cardtable);
|
||||
__ add(r_card_addr_0, r_card_base_1, AsmOperand(r_obj_0, lsr, CardTable::card_shift()));
|
||||
|
||||
// first quick check without barrier
|
||||
__ ldrb(r_tmp2, Address(r_card_addr_0));
|
||||
|
||||
__ cmp(r_tmp2, (int)G1CardTable::g1_young_card_val());
|
||||
__ b(recheck, ne);
|
||||
|
||||
__ bind(done);
|
||||
|
||||
__ pop(saved_regs);
|
||||
|
||||
__ ret();
|
||||
|
||||
__ bind(recheck);
|
||||
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp1);
|
||||
|
||||
// reload card state after the barrier that ensures the stored oop was visible
|
||||
__ ldrb(r_tmp2, Address(r_card_addr_0));
|
||||
|
||||
assert(CardTable::dirty_card_val() == 0, "adjust this code");
|
||||
__ cbz(r_tmp2, done);
|
||||
|
||||
// storing region crossing non-null, card is clean.
|
||||
// dirty card and log.
|
||||
|
||||
assert(0 == (int)CardTable::dirty_card_val(), "adjust this code");
|
||||
if ((ci_card_table_address_as<intptr_t>() & 0xff) == 0) {
|
||||
// Card table is aligned so the lowest byte of the table address base is zero.
|
||||
__ strb(r_card_base_1, Address(r_card_addr_0));
|
||||
} else {
|
||||
__ strb(__ zero_register(r_tmp2), Address(r_card_addr_0));
|
||||
}
|
||||
|
||||
__ ldr(r_index_2, queue_index);
|
||||
__ ldr(r_buffer_3, buffer);
|
||||
|
||||
__ subs(r_index_2, r_index_2, wordSize);
|
||||
__ b(runtime, lt); // go to runtime if now negative
|
||||
|
||||
__ str(r_index_2, queue_index);
|
||||
|
||||
__ str(r_card_addr_0, Address(r_buffer_3, r_index_2));
|
||||
|
||||
__ b(done);
|
||||
|
||||
__ bind(runtime);
|
||||
|
||||
__ save_live_registers();
|
||||
|
||||
assert(r_card_addr_0 == c_rarg0, "card_addr should be in R0");
|
||||
__ mov(c_rarg1, Rthread);
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), c_rarg0, c_rarg1);
|
||||
|
||||
__ restore_live_registers_without_return();
|
||||
|
||||
__ b(done);
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
#endif // COMPILER1
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2025, 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
|
||||
@ -32,9 +32,7 @@
|
||||
class LIR_Assembler;
|
||||
class StubAssembler;
|
||||
class G1PreBarrierStub;
|
||||
class G1PostBarrierStub;
|
||||
class G1PreBarrierStubC2;
|
||||
class G1PostBarrierStubC2;
|
||||
|
||||
class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
|
||||
protected:
|
||||
@ -66,10 +64,15 @@ public:
|
||||
#ifdef COMPILER1
|
||||
public:
|
||||
void gen_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrierStub* stub);
|
||||
void gen_post_barrier_stub(LIR_Assembler* ce, G1PostBarrierStub* stub);
|
||||
|
||||
void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm);
|
||||
void generate_c1_post_barrier_runtime_stub(StubAssembler* sasm);
|
||||
|
||||
void g1_write_barrier_post_c1(MacroAssembler* masm,
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register thread,
|
||||
Register tmp1,
|
||||
Register tmp2);
|
||||
#endif
|
||||
|
||||
#ifdef COMPILER2
|
||||
@ -89,9 +92,7 @@ public:
|
||||
Register tmp1,
|
||||
Register tmp2,
|
||||
Register tmp3,
|
||||
G1PostBarrierStubC2* c2_stub);
|
||||
void generate_c2_post_barrier_stub(MacroAssembler* masm,
|
||||
G1PostBarrierStubC2* stub) const;
|
||||
bool new_val_may_be_null);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2024, 2025, 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
|
||||
@ -63,13 +63,13 @@ static void write_barrier_post(MacroAssembler* masm,
|
||||
Register tmp1,
|
||||
Register tmp2,
|
||||
Register tmp3) {
|
||||
if (!G1PostBarrierStubC2::needs_barrier(node)) {
|
||||
if (!G1BarrierStubC2::needs_post_barrier(node)) {
|
||||
return;
|
||||
}
|
||||
Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
|
||||
G1BarrierSetAssembler* g1_asm = static_cast<G1BarrierSetAssembler*>(BarrierSet::barrier_set()->barrier_set_assembler());
|
||||
G1PostBarrierStubC2* const stub = G1PostBarrierStubC2::create(node);
|
||||
g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, Rthread, tmp1, tmp2, tmp3, stub);
|
||||
bool new_val_may_be_null = G1BarrierStubC2::post_new_val_may_be_null(node);
|
||||
g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, Rthread, tmp1, tmp2, tmp3, new_val_may_be_null);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2025, 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
|
||||
@ -364,7 +364,6 @@ class VFPSystemRegisterImpl : public AbstractRegisterImpl {
|
||||
// This does not seem to conflict with Rexception_pc
|
||||
// In case of issues, R3 might be OK but adapters calling the runtime would have to save it
|
||||
#define R5_mh R5 // MethodHandle register, used during the call setup
|
||||
#define Rmh_SP_save FP // for C1
|
||||
|
||||
/*
|
||||
* C++ Interpreter Register Defines
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user