mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-14 21:39:41 +01:00
Compare commits
291 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26de9e247a | ||
|
|
b530c0281b | ||
|
|
e70cb4e6c7 | ||
|
|
d89602a53f | ||
|
|
3bd9042054 | ||
|
|
525063be90 | ||
|
|
c1282b57f5 | ||
|
|
5ba69e1734 | ||
|
|
c96cbe481c | ||
|
|
a7db4feceb | ||
|
|
b86c3b7a68 | ||
|
|
475306b757 | ||
|
|
f016934184 | ||
|
|
2174f6646e | ||
|
|
16170678a7 | ||
|
|
2806adee2d | ||
|
|
ec38505720 | ||
|
|
d2d58dd6a8 | ||
|
|
b2a39c5767 | ||
|
|
679f526d89 | ||
|
|
2e472fe7ea | ||
|
|
88dafe564f | ||
|
|
8d9479910f | ||
|
|
9847086466 | ||
|
|
40861761c2 | ||
|
|
88378ed058 | ||
|
|
8569227473 | ||
|
|
f4ca41ad75 | ||
|
|
376051a9be | ||
|
|
a5071e010b | ||
|
|
28d8149c69 | ||
|
|
e9f7db3045 | ||
|
|
aba19334ea | ||
|
|
f3be138eb8 | ||
|
|
bc05893f82 | ||
|
|
dd8ae61643 | ||
|
|
ee98d26218 | ||
|
|
886386c039 | ||
|
|
438ab7c115 | ||
|
|
52c7ff1d81 | ||
|
|
ff499ef79f | ||
|
|
37a61720b6 | ||
|
|
7d42aa1513 | ||
|
|
6e9671a8a8 | ||
|
|
52a6c37558 | ||
|
|
075fed91bd | ||
|
|
30f93a29c2 | ||
|
|
4cf131a101 | ||
|
|
7286f5291d | ||
|
|
07fce8eff2 | ||
|
|
176606d0cb | ||
|
|
8ae309ebac | ||
|
|
841ab487f8 | ||
|
|
61ebe3b0c4 | ||
|
|
ca9635df33 | ||
|
|
8a4dc79e1a | ||
|
|
d78e8dab93 | ||
|
|
24823ba647 | ||
|
|
d47393bd82 | ||
|
|
387828a3f7 | ||
|
|
c4a83bd6f6 | ||
|
|
827c71dac9 | ||
|
|
2acb5bd992 | ||
|
|
c8fa3e21e6 | ||
|
|
57a65fe436 | ||
|
|
c90768c93b | ||
|
|
29397d29ba | ||
|
|
fc04750817 | ||
|
|
458e563cd9 | ||
|
|
71aac7a5fb | ||
|
|
09c6c4ff02 | ||
|
|
eb9e754b3a | ||
|
|
a40d397d5d | ||
|
|
7edd10e5fa | ||
|
|
d75d876edd | ||
|
|
e44276989f | ||
|
|
3560e680bc | ||
|
|
faa9c6909d | ||
|
|
ace010b38a | ||
|
|
be4614eb5e | ||
|
|
35a1b77da5 | ||
|
|
46965a096c | ||
|
|
700c25f5b4 | ||
|
|
631a9f60f3 | ||
|
|
ed9f3243f0 | ||
|
|
ade21a965f | ||
|
|
f0cfd361bd | ||
|
|
78623c95f2 | ||
|
|
f0e2e4311b | ||
|
|
3dc4bd8581 | ||
|
|
1d1cd32bc3 | ||
|
|
868f8745fa | ||
|
|
2a9c3589d9 | ||
|
|
5235cc987d | ||
|
|
3b1e56a427 | ||
|
|
3fbccb01dc | ||
|
|
ad31ec5c5f | ||
|
|
15cf8f8531 | ||
|
|
ade40741ca | ||
|
|
ea19e9c6aa | ||
|
|
d33dfe5cb2 | ||
|
|
27d5f5c237 | ||
|
|
df22fb322e | ||
|
|
c3cd1f1814 | ||
|
|
dd517c6404 | ||
|
|
83564ea5f3 | ||
|
|
bbe0079d98 | ||
|
|
730663649f | ||
|
|
1369c545ac | ||
|
|
4db7a1c3bb | ||
|
|
755722ced6 | ||
|
|
1cf9335b24 | ||
|
|
13c11487f7 | ||
|
|
028ec7e744 | ||
|
|
54b3ceeca2 | ||
|
|
30a0c61de0 | ||
|
|
409a39ec8d | ||
|
|
296c5b645a | ||
|
|
cc9ab5f197 | ||
|
|
1551928502 | ||
|
|
b67b71cd87 | ||
|
|
7eb25ec7b3 | ||
|
|
539da24863 | ||
|
|
a8e4229852 | ||
|
|
cbe329b90a | ||
|
|
06dd735342 | ||
|
|
9ab29f8dcd | ||
|
|
ba426d6887 | ||
|
|
18cdc903cf | ||
|
|
fcf8368eb1 | ||
|
|
a678416994 | ||
|
|
122bc7770e | ||
|
|
e9e694f4ef | ||
|
|
da1091eed9 | ||
|
|
c2477a5cad | ||
|
|
2cf5f01397 | ||
|
|
38042ad4e9 | ||
|
|
51238c4bdb | ||
|
|
9481d06e62 | ||
|
|
a5cf4210cd | ||
|
|
f9aec02f3c | ||
|
|
7455b1b527 | ||
|
|
d4fb30885b | ||
|
|
d786c49525 | ||
|
|
5852f3eafe | ||
|
|
be0e1c7b14 | ||
|
|
7c1d481d6d | ||
|
|
518ec97114 | ||
|
|
32d80e2caf | ||
|
|
19147f326c | ||
|
|
2a59243cba | ||
|
|
4fc6b0ffa4 | ||
|
|
28c82bf18d | ||
|
|
7263e25d9b | ||
|
|
f695ca5884 | ||
|
|
93fedc12db | ||
|
|
1230853343 | ||
|
|
dce7a5732e | ||
|
|
c53f845ec9 | ||
|
|
84c2379285 | ||
|
|
3b908c4781 | ||
|
|
1802601a12 | ||
|
|
6de23bf36e | ||
|
|
aff659aaf7 | ||
|
|
05745e3f1d | ||
|
|
e8768ae08d | ||
|
|
f6fe39ff11 | ||
|
|
e204242118 | ||
|
|
2d609557ff | ||
|
|
e0bad5153b | ||
|
|
424c58f3e9 | ||
|
|
14dab319a8 | ||
|
|
5fcac7c846 | ||
|
|
2f917bff5c | ||
|
|
7db69e6a12 | ||
|
|
f7dc257a20 | ||
|
|
97db670956 | ||
|
|
51be857f3c | ||
|
|
0f8e4e0a81 | ||
|
|
6313223bcd | ||
|
|
3bc5679cab | ||
|
|
be49dabd0d | ||
|
|
ac968c36d7 | ||
|
|
0ad6c9e3d9 | ||
|
|
fff2e580cd | ||
|
|
7b4d62c794 | ||
|
|
76637c53c5 | ||
|
|
59073fa3eb | ||
|
|
808a03927c | ||
|
|
459957f30a | ||
|
|
b98d13fc3c | ||
|
|
4f3de09672 | ||
|
|
1fde8b868a | ||
|
|
66aeb89469 | ||
|
|
a5122d7f6c | ||
|
|
c0a3b76958 | ||
|
|
7e1d26dd5c | ||
|
|
5584ba36c6 | ||
|
|
75d382d3db | ||
|
|
febf8af4b5 | ||
|
|
10335f60f9 | ||
|
|
ecff9c1ef7 | ||
|
|
a247d0c74b | ||
|
|
341b4e09b7 | ||
|
|
f696796e88 | ||
|
|
413dbf8757 | ||
|
|
f553819502 | ||
|
|
34351b7a79 | ||
|
|
b061b6678f | ||
|
|
dcdcd48d8f | ||
|
|
87ef73329f | ||
|
|
05f7f0ade2 | ||
|
|
6311dabe68 | ||
|
|
bdebf198bb | ||
|
|
20de541b13 | ||
|
|
b31454e362 | ||
|
|
0be0775a76 | ||
|
|
6dfb8120c2 | ||
|
|
a7dde578a8 | ||
|
|
692be57738 | ||
|
|
d02bc873f8 | ||
|
|
8b24851b9d | ||
|
|
c328f9589d | ||
|
|
fde5b16817 | ||
|
|
45a9ade337 | ||
|
|
62b7c5eaed | ||
|
|
69014cd55b | ||
|
|
5a97dbf606 | ||
|
|
2838a916ab | ||
|
|
d2ba3b1ef7 | ||
|
|
d632d743e0 | ||
|
|
ddbbd36e4b | ||
|
|
c8ad7b7f84 | ||
|
|
cf948548c3 | ||
|
|
7ece9e90c0 | ||
|
|
9320ef9b29 | ||
|
|
2a565ff368 | ||
|
|
493b5bd2fd | ||
|
|
f573f6d233 | ||
|
|
8a0a6f8c25 | ||
|
|
3d9d353edb | ||
|
|
1b621f5527 | ||
|
|
5463c9cd9a | ||
|
|
ac07355f55 | ||
|
|
4fb5c12813 | ||
|
|
d5a96e3f49 | ||
|
|
aadf36809c | ||
|
|
a3447ec656 | ||
|
|
b25ed57b76 | ||
|
|
df4ed7eff7 | ||
|
|
5718039a46 | ||
|
|
c51685267c | ||
|
|
7d903964fb | ||
|
|
6f4824068d | ||
|
|
e1fd663f22 | ||
|
|
d5214a4288 | ||
|
|
2611a49ea1 | ||
|
|
b8c0b2fd8c | ||
|
|
973bcdab81 | ||
|
|
6359b4ec23 | ||
|
|
ce4b257fa5 | ||
|
|
b270f30d10 | ||
|
|
486594d427 | ||
|
|
ce8399fd60 | ||
|
|
3c6459e1de | ||
|
|
92fd490f22 | ||
|
|
d13302f8b0 | ||
|
|
ce108446ca | ||
|
|
5c12a182e3 | ||
|
|
71800884f6 | ||
|
|
0c178beb69 | ||
|
|
6c13a3032f | ||
|
|
5e6bfc5eaa | ||
|
|
2c2d4d2cde | ||
|
|
0eb299af79 | ||
|
|
b893a2b2f7 | ||
|
|
05f950934e | ||
|
|
701bc3bbbe | ||
|
|
9e48b90c7f | ||
|
|
bad5edf146 | ||
|
|
f577385fc8 | ||
|
|
86623aa41d | ||
|
|
af5c49226c | ||
|
|
cb7e3d263a | ||
|
|
25dc4762b4 | ||
|
|
11e4a925be | ||
|
|
354ea4c28f | ||
|
|
959a443a9e | ||
|
|
4ed38f5ad5 | ||
|
|
fe4c0a2f04 | ||
|
|
519ecd352a |
@@ -1,7 +1,7 @@
|
||||
[general]
|
||||
project=jdk
|
||||
jbs=JDK
|
||||
version=22
|
||||
version=23
|
||||
|
||||
[checks]
|
||||
error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright 2015 Google, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
@@ -26,12 +27,17 @@ usage() {
|
||||
echo "$0 DIR ..."
|
||||
echo "Modifies in place all the java source files found"
|
||||
echo "in the given directories so that all java language modifiers"
|
||||
echo "are in the canonical order given by Modifier#toString()."
|
||||
echo "are in the canonical order."
|
||||
echo "Tries to get it right even within javadoc comments,"
|
||||
echo "and even if the list of modifiers spans 2 lines."
|
||||
echo
|
||||
echo "See:"
|
||||
echo "https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Modifier.html#toString-int-"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.1.1"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.3.1"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.4.3"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.8.3"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.1.1"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.4"
|
||||
echo
|
||||
echo "Example:"
|
||||
echo "$0 jdk/src/java.base jdk/test/java/{util,io,lang}"
|
||||
@@ -46,7 +52,7 @@ for dir in "${dirs[@]}"; do [[ -d "$dir" ]] || usage; done
|
||||
|
||||
declare -ar modifiers=(
|
||||
public protected private
|
||||
abstract static final transient
|
||||
abstract default static final sealed non-sealed transient
|
||||
volatile synchronized native strictfp
|
||||
)
|
||||
declare -r SAVE_IFS="$IFS"
|
||||
|
||||
@@ -1499,9 +1499,7 @@ like this:</p>
|
||||
--resolve-deps \
|
||||
buster \
|
||||
~/sysroot-arm64 \
|
||||
https://httpredir.debian.org/debian/</code></pre>
|
||||
<p>If the target architecture is <code>riscv64</code>, the path should
|
||||
be <code>debian-ports</code> instead of <code>debian</code>.</p></li>
|
||||
https://httpredir.debian.org/debian/</code></pre></li>
|
||||
<li><p>To create an Ubuntu-based chroot:</p>
|
||||
<pre><code>sudo debootstrap \
|
||||
--arch=arm64 \
|
||||
|
||||
@@ -1316,9 +1316,6 @@ For example, cross-compiling to AArch64 from x86_64 could be done like this:
|
||||
https://httpredir.debian.org/debian/
|
||||
```
|
||||
|
||||
If the target architecture is `riscv64`, the path should be `debian-ports`
|
||||
instead of `debian`.
|
||||
|
||||
* To create an Ubuntu-based chroot:
|
||||
|
||||
```
|
||||
|
||||
@@ -58,7 +58,7 @@ DEMO_MANIFEST := $(SUPPORT_OUTPUTDIR)/demos/java-main-manifest.mf
|
||||
# This rule will be depended on due to the MANIFEST line in SetupBuildDemo
|
||||
# and SetupBuildJvmtiDemo.
|
||||
$(eval $(call SetupTextFileProcessing, BUILD_JAVA_MANIFEST, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf.template, \
|
||||
OUTPUT_FILE := $(DEMO_MANIFEST), \
|
||||
REPLACEMENTS := \
|
||||
@@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION) ; \
|
||||
|
||||
@@ -33,7 +33,7 @@ include TextFileProcessing.gmk
|
||||
|
||||
# This rule will be depended on due to the MANIFEST line
|
||||
$(eval $(call SetupTextFileProcessing, BUILD_JAVA_MANIFEST, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf.template, \
|
||||
OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/java-main-manifest.mf, \
|
||||
REPLACEMENTS := \
|
||||
@@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION) ; \
|
||||
|
||||
@@ -69,7 +69,7 @@ ifeq ($(call isTargetOs, macosx), true)
|
||||
))
|
||||
|
||||
$(eval $(call SetupTextFileProcessing, BUILD_JDK_PLIST, \
|
||||
SOURCE_FILES := $(MACOSX_PLIST_SRC)/JDK-Info.plist, \
|
||||
SOURCE_FILES := $(MACOSX_PLIST_SRC)/JDK-Info.plist.template, \
|
||||
OUTPUT_FILE := $(JDK_MACOSX_CONTENTS_DIR)/Info.plist, \
|
||||
REPLACEMENTS := \
|
||||
@@ID@@ => $(MACOSX_BUNDLE_ID_BASE).jdk ; \
|
||||
@@ -82,7 +82,7 @@ ifeq ($(call isTargetOs, macosx), true)
|
||||
))
|
||||
|
||||
$(eval $(call SetupTextFileProcessing, BUILD_JRE_PLIST, \
|
||||
SOURCE_FILES := $(MACOSX_PLIST_SRC)/JRE-Info.plist, \
|
||||
SOURCE_FILES := $(MACOSX_PLIST_SRC)/JRE-Info.plist.template, \
|
||||
OUTPUT_FILE := $(JRE_MACOSX_CONTENTS_DIR)/Info.plist, \
|
||||
REPLACEMENTS := \
|
||||
@@ID@@ => $(MACOSX_BUNDLE_ID_BASE).jre ; \
|
||||
|
||||
@@ -744,9 +744,16 @@ endif
|
||||
|
||||
$(eval $(call SetupTarget, build-test-lib, \
|
||||
MAKEFILE := test/BuildTestLib, \
|
||||
TARGET := build-test-lib, \
|
||||
DEPS := exploded-image, \
|
||||
))
|
||||
|
||||
$(eval $(call SetupTarget, test-image-lib, \
|
||||
MAKEFILE := test/BuildTestLib, \
|
||||
TARGET := test-image-lib, \
|
||||
DEPS := build-test-lib, \
|
||||
))
|
||||
|
||||
ifeq ($(BUILD_FAILURE_HANDLER), true)
|
||||
# Builds the failure handler jtreg extension
|
||||
$(eval $(call SetupTarget, build-test-failure-handler, \
|
||||
@@ -781,7 +788,7 @@ endif
|
||||
|
||||
$(eval $(call SetupTarget, build-microbenchmark, \
|
||||
MAKEFILE := test/BuildMicrobenchmark, \
|
||||
DEPS := interim-langtools exploded-image, \
|
||||
DEPS := interim-langtools exploded-image build-test-lib, \
|
||||
))
|
||||
|
||||
################################################################################
|
||||
@@ -1264,7 +1271,7 @@ all-docs-bundles: docs-jdk-bundles docs-javase-bundles docs-reference-bundles
|
||||
# This target builds the test image
|
||||
test-image: prepare-test-image test-image-jdk-jtreg-native \
|
||||
test-image-demos-jdk test-image-libtest-jtreg-native \
|
||||
test-image-lib-native
|
||||
test-image-lib test-image-lib-native
|
||||
|
||||
ifneq ($(JVM_TEST_IMAGE_TARGETS), )
|
||||
# If JVM_TEST_IMAGE_TARGETS is externally defined, use it instead of the
|
||||
|
||||
@@ -448,17 +448,17 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
|
||||
AC_SUBST(CONFIGURESUPPORT_OUTPUTDIR)
|
||||
|
||||
# The spec.gmk file contains all variables for the make system.
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/spec.gmk:$AUTOCONF_DIR/spec.gmk.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/spec.gmk:$AUTOCONF_DIR/spec.gmk.template])
|
||||
# The bootcycle-spec.gmk file contains support for boot cycle builds.
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.template])
|
||||
# The buildjdk-spec.gmk file contains support for building a buildjdk when cross compiling.
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/buildjdk-spec.gmk:$AUTOCONF_DIR/buildjdk-spec.gmk.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/buildjdk-spec.gmk:$AUTOCONF_DIR/buildjdk-spec.gmk.template])
|
||||
# The compare.sh is used to compare the build output to other builds.
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/compare.sh:$AUTOCONF_DIR/compare.sh.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/compare.sh:$AUTOCONF_DIR/compare.sh.template])
|
||||
# The generated Makefile knows where the spec.gmk is and where the source is.
|
||||
# You can run make from the OUTPUTDIR, or from the top-level Makefile
|
||||
# which will look for generated configurations
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/Makefile:$AUTOCONF_DIR/Makefile.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/Makefile:$AUTOCONF_DIR/Makefile.template])
|
||||
])
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -110,6 +110,15 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
|
||||
CHECK_VALUE: [UTIL_CHECK_STRING_NON_EMPTY_PRINTABLE])
|
||||
AC_SUBST(COMPANY_NAME)
|
||||
|
||||
# Set the JDK RC Company name
|
||||
# Otherwise uses the value set for "vendor-name".
|
||||
UTIL_ARG_WITH(NAME: jdk-rc-company-name, TYPE: string,
|
||||
DEFAULT: $COMPANY_NAME,
|
||||
DESC: [Set JDK RC company name. This is used for CompanyName properties of MS Windows binaries.],
|
||||
DEFAULT_DESC: [from branding.conf],
|
||||
CHECK_VALUE: [UTIL_CHECK_STRING_NON_EMPTY_PRINTABLE])
|
||||
AC_SUBST(JDK_RC_COMPANY_NAME)
|
||||
|
||||
# The vendor URL, if any
|
||||
# Only set VENDOR_URL if '--with-vendor-url' was used and is not empty.
|
||||
# Otherwise we will use the value from "branding.conf" included above.
|
||||
|
||||
@@ -191,6 +191,7 @@ PRODUCT_NAME := @PRODUCT_NAME@
|
||||
PRODUCT_SUFFIX := @PRODUCT_SUFFIX@
|
||||
JDK_RC_PLATFORM_NAME := @JDK_RC_PLATFORM_NAME@
|
||||
JDK_RC_NAME := @JDK_RC_NAME@
|
||||
JDK_RC_COMPANY_NAME := @JDK_RC_COMPANY_NAME@
|
||||
COMPANY_NAME := @COMPANY_NAME@
|
||||
HOTSPOT_VM_DISTRO := @HOTSPOT_VM_DISTRO@
|
||||
MACOSX_BUNDLE_NAME_BASE := @MACOSX_BUNDLE_NAME_BASE@
|
||||
@@ -98,7 +98,7 @@ GLOBAL_VERSION_INFO_RESOURCE := $(TOPDIR)/src/java.base/windows/native/common/ve
|
||||
|
||||
JDK_RCFLAGS=$(RCFLAGS) \
|
||||
-D"JDK_VERSION_STRING=$(VERSION_STRING)" \
|
||||
-D"JDK_COMPANY=$(COMPANY_NAME)" \
|
||||
-D"JDK_COMPANY=$(JDK_RC_COMPANY_NAME)" \
|
||||
-D"JDK_VER=$(VERSION_NUMBER_FOUR_POSITIONS)" \
|
||||
-D"JDK_COPYRIGHT=Copyright \xA9 $(COPYRIGHT_YEAR)" \
|
||||
-D"JDK_NAME=$(JDK_RC_NAME) $(VERSION_SHORT)" \
|
||||
|
||||
@@ -112,7 +112,7 @@ define SetupBuildLauncherBody
|
||||
$1_PLIST_FILE := $$(SUPPORT_OUTPUTDIR)/native/$$(MODULE)/$1/Info.plist
|
||||
|
||||
$$(eval $$(call SetupTextFileProcessing, BUILD_PLIST_$1, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/bundle/cmdline-Info.plist, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/bundle/cmdline-Info.plist.template, \
|
||||
OUTPUT_FILE := $$($1_PLIST_FILE), \
|
||||
REPLACEMENTS := \
|
||||
@@ID@@ => $(MACOSX_BUNDLE_ID_BASE).$1 ; \
|
||||
|
||||
@@ -1206,7 +1206,7 @@ var getJibProfilesDependencies = function (input, common) {
|
||||
|
||||
jcov: {
|
||||
organization: common.organization,
|
||||
revision: "3.0-15-jdk-asm+1.0",
|
||||
revision: "3.0-16-jdk-asm+1.0",
|
||||
ext: "zip",
|
||||
environment_name: "JCOV_HOME",
|
||||
},
|
||||
|
||||
@@ -26,17 +26,17 @@
|
||||
# Default version, product, and vendor information to use,
|
||||
# unless overridden by configure
|
||||
|
||||
DEFAULT_VERSION_FEATURE=22
|
||||
DEFAULT_VERSION_FEATURE=23
|
||||
DEFAULT_VERSION_INTERIM=0
|
||||
DEFAULT_VERSION_UPDATE=0
|
||||
DEFAULT_VERSION_PATCH=0
|
||||
DEFAULT_VERSION_EXTRA1=0
|
||||
DEFAULT_VERSION_EXTRA2=0
|
||||
DEFAULT_VERSION_EXTRA3=0
|
||||
DEFAULT_VERSION_DATE=2024-03-19
|
||||
DEFAULT_VERSION_CLASSFILE_MAJOR=66 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
||||
DEFAULT_VERSION_DATE=2024-09-17
|
||||
DEFAULT_VERSION_CLASSFILE_MAJOR=67 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
||||
DEFAULT_VERSION_CLASSFILE_MINOR=0
|
||||
DEFAULT_VERSION_DOCS_API_SINCE=11
|
||||
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="21 22"
|
||||
DEFAULT_JDK_SOURCE_TARGET_VERSION=22
|
||||
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="21 22 23"
|
||||
DEFAULT_JDK_SOURCE_TARGET_VERSION=23
|
||||
DEFAULT_PROMOTED_VERSION_PRE=ea
|
||||
|
||||
@@ -223,6 +223,7 @@ JVM_VirtualThreadEnd
|
||||
JVM_VirtualThreadMount
|
||||
JVM_VirtualThreadUnmount
|
||||
JVM_VirtualThreadHideFrames
|
||||
JVM_VirtualThreadDisableSuspend
|
||||
|
||||
# Scoped values
|
||||
JVM_EnsureMaterializedForStackWalk_func
|
||||
|
||||
@@ -48,7 +48,7 @@ $(eval $(call IncludeCustomExtension, hotspot/gensrc/GenerateSources.gmk))
|
||||
|
||||
# Setup the hotspot launcher script for developer use
|
||||
$(eval $(call SetupTextFileProcessing, CREATE_HOTSPOT_LAUNCHER, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/scripts/hotspot.sh, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/scripts/hotspot.sh.template, \
|
||||
OUTPUT_FILE := $(JVM_OUTPUTDIR)/hotspot, \
|
||||
REPLACEMENTS := \
|
||||
@@LIBARCH@@ => $(OPENJDK_TARGET_CPU_LEGACY_LIB) ; \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2024, 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
|
||||
@@ -1289,25 +1289,58 @@ public class CLDRConverter {
|
||||
*/
|
||||
private static void generateTZDBShortNamesMap() throws IOException {
|
||||
Files.walk(Path.of(tzDataDir), 1, FileVisitOption.FOLLOW_LINKS)
|
||||
.filter(p -> p.toFile().isFile())
|
||||
.filter(p -> p.toFile().isFile() && !p.endsWith("jdk11_backward"))
|
||||
.forEach(p -> {
|
||||
try {
|
||||
String zone = null;
|
||||
String rule = null;
|
||||
String format = null;
|
||||
boolean inVanguard = false;
|
||||
boolean inRearguard = false;
|
||||
for (var line : Files.readAllLines(p)) {
|
||||
if (line.contains("#STDOFF")) continue;
|
||||
// Interpret the line in rearguard mode so that STD/DST
|
||||
// correctly handles negative DST cases, such as "GMT/IST"
|
||||
// vs. "IST/GMT" case for Europe/Dublin
|
||||
if (inVanguard) {
|
||||
if (line.startsWith("# Rearguard")) {
|
||||
inVanguard = false;
|
||||
inRearguard = true;
|
||||
}
|
||||
continue;
|
||||
} else if (line.startsWith("# Vanguard")) {
|
||||
inVanguard = true;
|
||||
continue;
|
||||
}
|
||||
if (inRearguard) {
|
||||
if (line.startsWith("# End of rearguard")) {
|
||||
inRearguard = false;
|
||||
continue;
|
||||
} else {
|
||||
if (line.startsWith("#\t")) {
|
||||
line = line.substring(1); // omit #
|
||||
}
|
||||
}
|
||||
}
|
||||
if (line.isBlank() || line.matches("^[ \t]*#.*")) {
|
||||
// ignore blank/comment lines
|
||||
continue;
|
||||
}
|
||||
// remove comments in-line
|
||||
line = line.replaceAll("[ \t]*#.*", "");
|
||||
|
||||
// Zone line
|
||||
if (line.startsWith("Zone")) {
|
||||
if (zone != null) {
|
||||
tzdbShortNamesMap.put(zone, format + NBSP + rule);
|
||||
}
|
||||
var zl = line.split("[ \t]+", -1);
|
||||
zone = zl[1];
|
||||
rule = zl[3];
|
||||
format = zl[4];
|
||||
} else {
|
||||
if (zone != null) {
|
||||
if (line.isBlank()) {
|
||||
if (line.startsWith("Rule") ||
|
||||
line.startsWith("Link")) {
|
||||
tzdbShortNamesMap.put(zone, format + NBSP + rule);
|
||||
zone = null;
|
||||
rule = null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2023, 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,6 +32,7 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
@@ -339,9 +340,15 @@ public class GenerateCurrencyData {
|
||||
validCurrencyCodes.substring(i * 7 + 3, i * 7 + 6));
|
||||
checkCurrencyCode(currencyCode);
|
||||
int tableEntry = mainTable[(currencyCode.charAt(0) - 'A') * A_TO_Z + (currencyCode.charAt(1) - 'A')];
|
||||
if (tableEntry == INVALID_COUNTRY_ENTRY ||
|
||||
(tableEntry & SPECIAL_CASE_COUNTRY_MASK) != 0 ||
|
||||
(tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) != (currencyCode.charAt(2) - 'A')) {
|
||||
|
||||
// Do not allow a future currency to be classified as an otherCurrency,
|
||||
// otherwise it will leak out into Currency:getAvailableCurrencies
|
||||
boolean futureCurrency = Arrays.asList(specialCaseNewCurrencies).contains(currencyCode);
|
||||
boolean simpleCurrency = (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) == (currencyCode.charAt(2) - 'A');
|
||||
|
||||
// If neither a simple currency, or one defined in the future
|
||||
// then the current currency is applicable to be added to the otherTable
|
||||
if (!futureCurrency && !simpleCurrency) {
|
||||
if (otherCurrenciesCount == maxOtherCurrencies) {
|
||||
throw new RuntimeException("too many other currencies");
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ ifeq ($(call isTargetOs, linux)+$(call isTargetCpu, x86_64)+$(INCLUDE_COMPILER2)
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
OPTIMIZATION := HIGH, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB), \
|
||||
CXXFLAGS := $(CXXFLAGS_JDKLIB), \
|
||||
CXXFLAGS := $(CXXFLAGS_JDKLIB) -std=c++17, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LIBS := $(LIBCXX), \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2024, 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
|
||||
@@ -47,7 +47,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBINSTRUMENT, \
|
||||
LDFLAGS_macosx := -L$(call FindLibDirForModule, java.base), \
|
||||
LDFLAGS_aix := -L$(SUPPORT_OUTPUTDIR)/native/java.base, \
|
||||
LIBS := $(JDKLIB_LIBS), \
|
||||
LIBS_unix := -ljava -ljvm $(LIBZ_LIBS), \
|
||||
LIBS_unix := $(LIBZ_LIBS), \
|
||||
LIBS_linux := -ljli $(LIBDL), \
|
||||
LIBS_aix := -liconv -ljli_static $(LIBDL), \
|
||||
LIBS_macosx := -ljli -liconv -framework Cocoa -framework Security \
|
||||
|
||||
@@ -53,11 +53,10 @@ JMH_UNPACKED_DIR := $(MICROBENCHMARK_OUTPUT)/jmh_jars
|
||||
JMH_UNPACKED_JARS_DONE := $(JMH_UNPACKED_DIR)/_unpacked.marker
|
||||
|
||||
# External dependencies
|
||||
JMH_COMPILE_JARS := $(JMH_CORE_JAR) $(JMH_GENERATOR_JAR)
|
||||
WHITEBOX_JAR := $(SUPPORT_OUTPUTDIR)/test/lib/wb.jar
|
||||
JMH_COMPILE_JARS := $(JMH_CORE_JAR) $(JMH_GENERATOR_JAR) $(WHITEBOX_JAR)
|
||||
JMH_RUNTIME_JARS := $(JMH_CORE_JAR) $(JMH_COMMONS_MATH_JAR) $(JMH_JOPT_SIMPLE_JAR)
|
||||
|
||||
MICROBENCHMARK_CLASSPATH := $(call PathList, $(JMH_COMPILE_JARS))
|
||||
|
||||
# Native dependencies
|
||||
MICROBENCHMARK_NATIVE_SRC_DIRS := $(MICROBENCHMARK_SRC)
|
||||
MICROBENCHMARK_NATIVE_OUTPUT := $(MICROBENCHMARK_OUTPUT)/native
|
||||
@@ -92,24 +91,28 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \
|
||||
$(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \
|
||||
TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \
|
||||
SMALL_JAVA := false, \
|
||||
CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \
|
||||
DISABLED_WARNINGS := restricted this-escape processing rawtypes cast serial preview, \
|
||||
CLASSPATH := $(JMH_COMPILE_JARS), \
|
||||
DISABLED_WARNINGS := restricted this-escape processing rawtypes cast \
|
||||
serial preview, \
|
||||
SRC := $(MICROBENCHMARK_SRC), \
|
||||
BIN := $(MICROBENCHMARK_CLASSES), \
|
||||
JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \
|
||||
--add-exports java.base/sun.invoke.util=ALL-UNNAMED \
|
||||
JAVAC_FLAGS := \
|
||||
--add-exports java.base/jdk.internal.classfile.impl=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.vm=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.event=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.vm=ALL-UNNAMED \
|
||||
--add-exports java.base/sun.invoke.util=ALL-UNNAMED \
|
||||
--add-exports java.base/sun.security.util=ALL-UNNAMED \
|
||||
--enable-preview \
|
||||
-processor org.openjdk.jmh.generators.BenchmarkProcessor, \
|
||||
JAVA_FLAGS := --add-modules jdk.unsupported --limit-modules java.management \
|
||||
JAVA_FLAGS := \
|
||||
--add-exports java.base/jdk.internal.vm=ALL-UNNAMED \
|
||||
--enable-preview, \
|
||||
--add-modules jdk.unsupported \
|
||||
--enable-preview \
|
||||
--limit-modules java.management, \
|
||||
))
|
||||
|
||||
$(BUILD_JDK_MICROBENCHMARK): $(JMH_COMPILE_JARS)
|
||||
|
||||
@@ -23,12 +23,22 @@
|
||||
# questions.
|
||||
#
|
||||
|
||||
################################################################################
|
||||
# This file builds the Java components of testlib.
|
||||
# It also covers the test-image part, where the built files are copied to the
|
||||
# test image.
|
||||
################################################################################
|
||||
|
||||
default: all
|
||||
|
||||
include $(SPEC)
|
||||
include MakeBase.gmk
|
||||
include JavaCompilation.gmk
|
||||
|
||||
################################################################################
|
||||
# Targets for building the test lib jars
|
||||
################################################################################
|
||||
|
||||
TARGETS :=
|
||||
|
||||
TEST_LIB_SOURCE_DIR := $(TOPDIR)/test/lib
|
||||
@@ -63,8 +73,21 @@ $(eval $(call SetupJavaCompilation, BUILD_TEST_LIB_JAR, \
|
||||
|
||||
TARGETS += $(BUILD_TEST_LIB_JAR)
|
||||
|
||||
##########################################################################################
|
||||
build-test-lib: $(TARGETS)
|
||||
|
||||
all: $(TARGETS)
|
||||
################################################################################
|
||||
# Targets for building test-image.
|
||||
################################################################################
|
||||
|
||||
.PHONY: default all
|
||||
# Copy the jars to the test image.
|
||||
$(eval $(call SetupCopyFiles, COPY_LIBTEST_JARS, \
|
||||
DEST := $(TEST_IMAGE_DIR)/lib-test, \
|
||||
FILES := $(BUILD_WB_JAR_JAR) $(BUILD_TEST_LIB_JAR_JAR), \
|
||||
))
|
||||
#
|
||||
|
||||
test-image-lib: $(COPY_LIBTEST_JARS)
|
||||
|
||||
all: build-test-lib
|
||||
|
||||
.PHONY: default all build-test-lib test-image-lib
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2020, 2024, 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
|
||||
@@ -45,6 +45,10 @@ BUILD_LIBTEST_OUTPUT_DIR := $(OUTPUTDIR)/support/test/lib/native
|
||||
|
||||
BUILD_LIBTEST_IMAGE_DIR := $(TEST_IMAGE_DIR)/lib
|
||||
|
||||
ifeq ($(call isTargetOs, windows), false)
|
||||
BUILD_LIBTEST_LIBRARIES_EXCLUDE += libFileUtils.c
|
||||
endif
|
||||
|
||||
# This evaluation is expensive and should only be done if this target was
|
||||
# explicitly called.
|
||||
ifneq ($(filter build-test-lib-native, $(MAKECMDGOALS)), )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2015, 2024, 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
|
||||
@@ -857,6 +857,11 @@ else
|
||||
exeinvoke.c exestack-gap.c exestack-tls.c libAsyncGetCallTraceTest.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(call And, $(call isTargetOs, linux) $(call isTargetCpu, aarch64)), false)
|
||||
BUILD_HOTSPOT_JTREG_EXCLUDE += libTestSVEWithJNI.c
|
||||
endif
|
||||
|
||||
|
||||
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exesigtest := -ljvm
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -1716,7 +1716,7 @@ public class Intro extends JPanel {
|
||||
this.beginning = beg;
|
||||
this.ending = end;
|
||||
fm = surf.getMetrics(font);
|
||||
java.util.Arrays.sort(members);
|
||||
Arrays.sort(members);
|
||||
cast.add("CONTRIBUTORS");
|
||||
cast.add(" ");
|
||||
cast.addAll(Arrays.asList(members));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2003, 2024, 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.
|
||||
//
|
||||
@@ -8237,6 +8237,24 @@ instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// ============================================================================
|
||||
// VerifyVectorAlignment Instruction
|
||||
|
||||
instruct verify_vector_alignment(iRegP addr, immL_positive_bitmaskI mask, rFlagsReg cr) %{
|
||||
match(Set addr (VerifyVectorAlignment addr mask));
|
||||
effect(KILL cr);
|
||||
format %{ "verify_vector_alignment $addr $mask \t! verify alignment" %}
|
||||
ins_encode %{
|
||||
Label Lskip;
|
||||
// check if masked bits of addr are zero
|
||||
__ tst($addr$$Register, $mask$$constant);
|
||||
__ br(Assembler::EQ, Lskip);
|
||||
__ stop("verify_vector_alignment found a misaligned vector memory access");
|
||||
__ bind(Lskip);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// ============================================================================
|
||||
// MemBar Instruction
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -282,7 +282,8 @@ void LIR_Assembler::osr_entry() {
|
||||
__ bind(L);
|
||||
}
|
||||
#endif
|
||||
__ ldp(r19, r20, Address(OSR_buf, slot_offset));
|
||||
__ ldr(r19, Address(OSR_buf, slot_offset));
|
||||
__ ldr(r20, Address(OSR_buf, slot_offset + BytesPerWord));
|
||||
__ str(r19, frame_map()->address_for_monitor_lock(i));
|
||||
__ str(r20, frame_map()->address_for_monitor_object(i));
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "code/compiledIC.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
@@ -90,9 +91,9 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
address stub = find_stub();
|
||||
guarantee(stub != nullptr, "stub not found");
|
||||
|
||||
if (TraceICs) {
|
||||
{
|
||||
ResourceMark rm;
|
||||
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
p2i(instruction_address()),
|
||||
callee->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
@@ -156,8 +156,6 @@
|
||||
static void verify_deopt_original_pc( CompiledMethod* nm, intptr_t* unextended_sp);
|
||||
#endif
|
||||
|
||||
const ImmutableOopMap* get_oop_map() const;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, 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.
|
||||
*
|
||||
@@ -195,7 +195,7 @@ inline bool frame::equal(frame other) const {
|
||||
&& unextended_sp() == other.unextended_sp()
|
||||
&& fp() == other.fp()
|
||||
&& pc() == other.pc();
|
||||
assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
|
||||
assert(!ret || (cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -359,20 +359,6 @@ inline int frame::sender_sp_ret_address_offset() {
|
||||
return frame::sender_sp_offset - frame::return_addr_offset;
|
||||
}
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
if (_cb == nullptr) return nullptr;
|
||||
if (_cb->oop_maps() != nullptr) {
|
||||
NativePostCallNop* nop = nativePostCallNop_at(_pc);
|
||||
if (nop != nullptr && nop->displacement() != 0) {
|
||||
int slot = ((nop->displacement() >> 24) & 0xff);
|
||||
return _cb->oop_map_for_slot(slot, _pc);
|
||||
}
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::sender
|
||||
inline frame frame::sender(RegisterMap* map) const {
|
||||
|
||||
@@ -42,8 +42,12 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
// and Operational Models for ARMv8"
|
||||
#define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
// According to the ARMv8 ARM, "Concurrent modification and execution
|
||||
// of instructions can lead to the resulting instruction performing
|
||||
// any behavior that can be achieved by executing any sequence of
|
||||
|
||||
@@ -193,4 +193,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Is SIMD sort supported for this CPU?
|
||||
static bool supports_simd_sort(BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // CPU_AARCH64_MATCHER_AARCH64_HPP
|
||||
|
||||
@@ -560,18 +560,23 @@ static bool is_movk_to_zr(uint32_t insn) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativePostCallNop::patch(jint diff) {
|
||||
bool NativePostCallNop::patch(int32_t oopmap_slot, int32_t cb_offset) {
|
||||
if (((oopmap_slot & 0xff) != oopmap_slot) || ((cb_offset & 0xffffff) != cb_offset)) {
|
||||
return false; // cannot encode
|
||||
}
|
||||
uint32_t data = ((uint32_t)oopmap_slot << 24) | cb_offset;
|
||||
#ifdef ASSERT
|
||||
assert(diff != 0, "must be");
|
||||
assert(data != 0, "must be");
|
||||
uint32_t insn1 = uint_at(4);
|
||||
uint32_t insn2 = uint_at(8);
|
||||
assert (is_movk_to_zr(insn1) && is_movk_to_zr(insn2), "must be");
|
||||
#endif
|
||||
|
||||
uint32_t lo = diff & 0xffff;
|
||||
uint32_t hi = (uint32_t)diff >> 16;
|
||||
uint32_t lo = data & 0xffff;
|
||||
uint32_t hi = data >> 16;
|
||||
Instruction_aarch64::patch(addr_at(4), 20, 5, lo);
|
||||
Instruction_aarch64::patch(addr_at(8), 20, 5, hi);
|
||||
return true; // successfully encoded
|
||||
}
|
||||
|
||||
void NativeDeoptInstruction::verify() {
|
||||
|
||||
@@ -691,16 +691,20 @@ public:
|
||||
return (insns & 0xffe0001fffffffff) == 0xf280001fd503201f;
|
||||
}
|
||||
|
||||
jint displacement() const {
|
||||
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const {
|
||||
uint64_t movk_insns = *(uint64_t*)addr_at(4);
|
||||
uint32_t lo = (movk_insns >> 5) & 0xffff;
|
||||
uint32_t hi = (movk_insns >> (5 + 32)) & 0xffff;
|
||||
uint32_t result = (hi << 16) | lo;
|
||||
|
||||
return (jint)result;
|
||||
uint32_t data = (hi << 16) | lo;
|
||||
if (data == 0) {
|
||||
return false; // no information encoded
|
||||
}
|
||||
cb_offset = (data & 0xffffff);
|
||||
oopmap_slot = (data >> 24) & 0xff;
|
||||
return true; // decoding succeeded
|
||||
}
|
||||
|
||||
void patch(jint diff);
|
||||
bool patch(int32_t oopmap_slot, int32_t cb_offset);
|
||||
void make_deopt();
|
||||
};
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
|
||||
uint int_args = 0;
|
||||
uint fp_args = 0;
|
||||
uint stk_args = 0; // inc by 2 each time
|
||||
uint stk_args = 0;
|
||||
|
||||
for (int i = 0; i < total_args_passed; i++) {
|
||||
switch (sig_bt[i]) {
|
||||
@@ -322,8 +322,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (int_args < Argument::n_int_register_parameters_j) {
|
||||
regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set1(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
stk_args += 1;
|
||||
}
|
||||
break;
|
||||
case T_VOID:
|
||||
@@ -340,6 +341,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (int_args < Argument::n_int_register_parameters_j) {
|
||||
regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set2(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
}
|
||||
@@ -348,8 +350,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (fp_args < Argument::n_float_register_parameters_j) {
|
||||
regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set1(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
stk_args += 1;
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
@@ -357,6 +360,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (fp_args < Argument::n_float_register_parameters_j) {
|
||||
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set2(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
}
|
||||
@@ -367,7 +371,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
}
|
||||
|
||||
return align_up(stk_args, 2);
|
||||
return stk_args;
|
||||
}
|
||||
|
||||
// Patch the callers callsite with entry to compiled code if it exists.
|
||||
|
||||
@@ -3603,11 +3603,9 @@ void TemplateTable::_new() {
|
||||
// get InstanceKlass
|
||||
__ load_resolved_klass_at_offset(r4, r3, r4, rscratch1);
|
||||
|
||||
// make sure klass is initialized & doesn't have finalizer
|
||||
// make sure klass is fully initialized
|
||||
__ ldrb(rscratch1, Address(r4, InstanceKlass::init_state_offset()));
|
||||
__ cmp(rscratch1, (u1)InstanceKlass::fully_initialized);
|
||||
__ br(Assembler::NE, slow_case);
|
||||
// make sure klass is initialized
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "Optimization requires support for fast class initialization checks");
|
||||
__ clinit_barrier(r4, rscratch1, nullptr /*L_fast_path*/, &slow_case);
|
||||
|
||||
// get instance_size in InstanceKlass (scaled to a count of bytes)
|
||||
__ ldrw(r3,
|
||||
|
||||
@@ -165,6 +165,7 @@ enum Ampere_CPU_Model {
|
||||
static int dcache_line_size() { return _dcache_line_size; }
|
||||
static int get_initial_sve_vector_length() { return _initial_sve_vector_length; };
|
||||
|
||||
// Aarch64 supports fast class initialization checks
|
||||
static bool supports_fast_class_init_checks() { return true; }
|
||||
constexpr static bool supports_stack_watermark_barrier() { return true; }
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2008, 2024, 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
|
||||
@@ -9193,7 +9193,7 @@ instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dum
|
||||
ins_encode %{
|
||||
__ mov($zero$$Register, 0);
|
||||
__ mov($temp$$Register, $cnt$$Register);
|
||||
Label(loop);
|
||||
Label loop;
|
||||
__ bind(loop);
|
||||
__ subs($temp$$Register, $temp$$Register, 4);
|
||||
__ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, 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
|
||||
@@ -175,7 +175,7 @@ class Address {
|
||||
if (_index == noreg) {
|
||||
assert(-256 < _disp && _disp < 256, "encoding constraint");
|
||||
return _mode | up(_disp) << 23 | 1 << 22 | _base->encoding() << 16 |
|
||||
(abs(_disp) & 0xf0) << 4 | abs(_disp) & 0x0f;
|
||||
(abs(_disp) & 0xf0) << 4 | (abs(_disp) & 0x0f);
|
||||
} else {
|
||||
assert(_index != PC && (_mode == basic_offset || _index != _base), "unpredictable instruction");
|
||||
assert(_disp == 0 && _shift == lsl && _shift_imm == 0, "encoding constraint");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, 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
|
||||
@@ -2640,8 +2640,8 @@ void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* arg
|
||||
|
||||
|
||||
void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {
|
||||
assert(src->is_double_cpu() && dest->is_address() ||
|
||||
src->is_address() && dest->is_double_cpu(),
|
||||
assert((src->is_double_cpu() && dest->is_address()) ||
|
||||
(src->is_address() && dest->is_double_cpu()),
|
||||
"Simple move_op is called for all other cases");
|
||||
|
||||
int null_check_offset;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/nativeInst.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
@@ -105,9 +106,9 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
address stub = find_stub();
|
||||
guarantee(stub != nullptr, "stub not found");
|
||||
|
||||
if (TraceICs) {
|
||||
{
|
||||
ResourceMark rm;
|
||||
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
p2i(instruction_address()),
|
||||
callee->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
@@ -99,8 +99,6 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
const ImmutableOopMap* get_oop_map() const;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, 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
|
||||
@@ -93,7 +93,7 @@ inline bool frame::equal(frame other) const {
|
||||
&& unextended_sp() == other.unextended_sp()
|
||||
&& fp() == other.fp()
|
||||
&& pc() == other.pc();
|
||||
assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
|
||||
assert(!ret || (cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -218,20 +218,6 @@ inline int frame::frame_size() const {
|
||||
return sender_sp() - sp();
|
||||
}
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
if (_cb == nullptr) return nullptr;
|
||||
if (_cb->oop_maps() != nullptr) {
|
||||
NativePostCallNop* nop = nativePostCallNop_at(_pc);
|
||||
if (nop != nullptr && nop->displacement() != 0) {
|
||||
int slot = ((nop->displacement() >> 24) & 0xff);
|
||||
return _cb->oop_map_for_slot(slot, _pc);
|
||||
}
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline int frame::compiled_frame_stack_argsize() const {
|
||||
Unimplemented();
|
||||
return 0;
|
||||
|
||||
@@ -49,8 +49,12 @@ const bool HaveVFP = true;
|
||||
// arm32 is not specified as multi-copy-atomic
|
||||
// So we must not #define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#define STUBROUTINES_MD_HPP "stubRoutines_arm.hpp"
|
||||
#define INTERP_MASM_MD_HPP "interp_masm_arm.hpp"
|
||||
#define TEMPLATETABLE_MD_HPP "templateTable_arm.hpp"
|
||||
|
||||
@@ -303,15 +303,19 @@ void InterpreterMacroAssembler::load_field_entry(Register cache, Register index,
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::load_method_entry(Register cache, Register index, int bcp_offset) {
|
||||
assert_different_registers(cache, index);
|
||||
|
||||
// Get index out of bytecode pointer
|
||||
get_index_at_bcp(index, bcp_offset, cache /* as tmp */, sizeof(u2));
|
||||
|
||||
// sizeof(ResolvedMethodEntry) is not a power of 2 on Arm, so can't use shift
|
||||
mov(cache, sizeof(ResolvedMethodEntry));
|
||||
mul(index, index, cache); // Scale the index to be the entry index * sizeof(ResolvedMethodEntry)
|
||||
|
||||
// load constant pool cache pointer
|
||||
ldr(cache, Address(FP, frame::interpreter_frame_cache_offset * wordSize));
|
||||
// Get address of method entries array
|
||||
ldr(cache, Address(cache, ConstantPoolCache::method_entries_offset()));
|
||||
ldr(cache, Address(cache, in_bytes(ConstantPoolCache::method_entries_offset())));
|
||||
add(cache, cache, Array<ResolvedMethodEntry>::base_offset_in_bytes());
|
||||
add(cache, cache, index);
|
||||
}
|
||||
|
||||
@@ -186,4 +186,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Is SIMD sort supported for this CPU?
|
||||
static bool supports_simd_sort(BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // CPU_ARM_MATCHER_ARM_HPP
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, 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
|
||||
@@ -162,7 +162,7 @@ void NativeMovConstReg::set_data(intptr_t x, address pc) {
|
||||
unsigned int hi = (unsigned int)(x >> 16);
|
||||
this->set_encoding((this->encoding() & 0xfff0f000) | (lo & 0xf000) << 4 | (lo & 0xfff));
|
||||
next->set_encoding((next->encoding() & 0xfff0f000) | (hi & 0xf000) << 4 | (hi & 0xfff));
|
||||
} else if (oop_addr == nullptr & metadata_addr == nullptr) {
|
||||
} else if (oop_addr == nullptr && metadata_addr == nullptr) {
|
||||
// A static ldr_literal (without oop or metadata relocation)
|
||||
assert(is_ldr_literal(), "must be");
|
||||
int offset = ldr_offset();
|
||||
@@ -341,10 +341,6 @@ void NativePostCallNop::make_deopt() {
|
||||
NativeDeoptInstruction::insert(addr_at(0));
|
||||
}
|
||||
|
||||
void NativePostCallNop::patch(jint diff) {
|
||||
// unsupported for now
|
||||
}
|
||||
|
||||
void NativeDeoptInstruction::verify() {
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, 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
|
||||
@@ -396,7 +396,7 @@ class NativeMovConstReg: public NativeInstruction {
|
||||
inline NativeMovConstReg* nativeMovConstReg_at(address address) {
|
||||
NativeInstruction* ni = nativeInstruction_at(address);
|
||||
assert(ni->is_ldr_literal() || ni->is_pc_rel() ||
|
||||
ni->is_movw() && VM_Version::supports_movw(), "must be");
|
||||
(ni->is_movw() && VM_Version::supports_movw()), "must be");
|
||||
return (NativeMovConstReg*)address;
|
||||
}
|
||||
|
||||
@@ -438,8 +438,8 @@ inline NativeCall* nativeCall_before(address return_address) {
|
||||
class NativePostCallNop: public NativeInstruction {
|
||||
public:
|
||||
bool check() const { return is_nop(); }
|
||||
int displacement() const { return 0; }
|
||||
void patch(jint diff);
|
||||
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const { return false; }
|
||||
bool patch(int32_t oopmap_slot, int32_t cb_offset) { return false; }
|
||||
void make_deopt();
|
||||
};
|
||||
|
||||
|
||||
@@ -441,7 +441,6 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
}
|
||||
|
||||
if (slot & 1) slot++;
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
||||
@@ -370,17 +370,16 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
if (index_size == sizeof(u4)) {
|
||||
__ load_resolved_indy_entry(Rcache, Rindex);
|
||||
__ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedIndyEntry::num_parameters_offset())));
|
||||
__ check_stack_top();
|
||||
__ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize));
|
||||
} else {
|
||||
// Pop N words from the stack
|
||||
assert(index_size == sizeof(u2), "Can only be u2");
|
||||
__ load_method_entry(Rcache, Rindex);
|
||||
__ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedIndyEntry::num_parameters_offset())));
|
||||
__ check_stack_top();
|
||||
__ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize));
|
||||
__ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedMethodEntry::num_parameters_offset())));
|
||||
}
|
||||
|
||||
__ check_stack_top();
|
||||
__ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize));
|
||||
|
||||
__ convert_retval_to_tos(state);
|
||||
|
||||
__ check_and_handle_popframe();
|
||||
|
||||
@@ -3666,15 +3666,15 @@ void TemplateTable::prepare_invoke(Register Rcache, Register recv) {
|
||||
// load receiver if needed (after extra argument is pushed so parameter size is correct)
|
||||
if (load_receiver) {
|
||||
__ ldrh(recv, Address(Rcache, in_bytes(ResolvedMethodEntry::num_parameters_offset())));
|
||||
Address recv_addr = __ receiver_argument_address(Rstack_top, Rtemp, recv);
|
||||
__ ldr(recv, recv_addr);
|
||||
__ add(recv, Rstack_top, AsmOperand(recv, lsl, Interpreter::logStackElementSize));
|
||||
__ ldr(recv, Address(recv, -Interpreter::stackElementSize));
|
||||
__ verify_oop(recv);
|
||||
}
|
||||
|
||||
// load return address
|
||||
{ const address table = (address) Interpreter::invoke_return_entry_table_for(code);
|
||||
__ mov_slow(Rtemp, table);
|
||||
__ ldr(LR, Address::indexed_ptr(Rtemp, ret_type));
|
||||
__ mov_slow(LR, table);
|
||||
__ ldr(LR, Address::indexed_ptr(LR, ret_type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3744,10 +3744,13 @@ void TemplateTable::invokevirtual(int byte_no) {
|
||||
void TemplateTable::invokespecial(int byte_no) {
|
||||
transition(vtos, vtos);
|
||||
assert(byte_no == f1_byte, "use this argument");
|
||||
|
||||
const Register Rrecv = R2_tmp;
|
||||
load_resolved_method_entry_special_or_static(R2_tmp, // ResolvedMethodEntry*
|
||||
const Register Rflags = R3_tmp;
|
||||
|
||||
load_resolved_method_entry_special_or_static(Rrecv, // ResolvedMethodEntry*
|
||||
Rmethod, // Method*
|
||||
R3_tmp); // Flags
|
||||
Rflags); // Flags
|
||||
prepare_invoke(Rrecv, Rrecv);
|
||||
__ verify_oop(Rrecv);
|
||||
__ null_check(Rrecv, Rtemp);
|
||||
@@ -3760,12 +3763,16 @@ void TemplateTable::invokespecial(int byte_no) {
|
||||
void TemplateTable::invokestatic(int byte_no) {
|
||||
transition(vtos, vtos);
|
||||
assert(byte_no == f1_byte, "use this argument");
|
||||
load_resolved_method_entry_special_or_static(R2_tmp, // ResolvedMethodEntry*
|
||||
|
||||
const Register Rrecv = R2_tmp;
|
||||
const Register Rflags = R3_tmp;
|
||||
|
||||
load_resolved_method_entry_special_or_static(Rrecv, // ResolvedMethodEntry*
|
||||
Rmethod, // Method*
|
||||
R3_tmp); // Flags
|
||||
prepare_invoke(R2_tmp, R2_tmp);
|
||||
Rflags); // Flags
|
||||
prepare_invoke(Rrecv, Rrecv);
|
||||
// do the call
|
||||
__ profile_call(R2_tmp);
|
||||
__ profile_call(Rrecv);
|
||||
__ jump_from_interpreted(Rmethod);
|
||||
}
|
||||
|
||||
@@ -3788,10 +3795,10 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
const Register Rflags = R3_tmp;
|
||||
const Register Rklass = R2_tmp; // Note! Same register with Rrecv
|
||||
|
||||
load_resolved_method_entry_interface(R2_tmp, // ResolvedMethodEntry*
|
||||
R1_tmp, // Klass*
|
||||
load_resolved_method_entry_interface(Rrecv, // ResolvedMethodEntry*
|
||||
Rinterf, // Klass*
|
||||
Rmethod, // Method* or itable/vtable index
|
||||
R3_tmp); // Flags
|
||||
Rflags); // Flags
|
||||
prepare_invoke(Rrecv, Rrecv);
|
||||
|
||||
// First check for Object case, then private interface method,
|
||||
|
||||
@@ -167,9 +167,9 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
address stub = find_stub();
|
||||
guarantee(stub != nullptr, "stub not found");
|
||||
|
||||
if (TraceICs) {
|
||||
{
|
||||
ResourceMark rm;
|
||||
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
p2i(instruction_address()),
|
||||
callee->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
@@ -400,8 +400,6 @@
|
||||
|
||||
public:
|
||||
|
||||
const ImmutableOopMap* get_oop_map() const;
|
||||
|
||||
// Constructors
|
||||
inline frame(intptr_t* sp, intptr_t* fp, address pc);
|
||||
inline frame(intptr_t* sp, address pc, intptr_t* unextended_sp = nullptr, intptr_t* fp = nullptr, CodeBlob* cb = nullptr);
|
||||
|
||||
@@ -78,8 +78,8 @@ inline void frame::setup() {
|
||||
// Continuation frames on the java heap are not aligned.
|
||||
// When thawing interpreted frames the sp can be unaligned (see new_stack_frame()).
|
||||
assert(_on_heap ||
|
||||
(is_aligned(_sp, alignment_in_bytes) || is_interpreted_frame()) &&
|
||||
(is_aligned(_fp, alignment_in_bytes) || !is_fully_initialized()),
|
||||
((is_aligned(_sp, alignment_in_bytes) || is_interpreted_frame()) &&
|
||||
(is_aligned(_fp, alignment_in_bytes) || !is_fully_initialized())),
|
||||
"invalid alignment sp:" PTR_FORMAT " unextended_sp:" PTR_FORMAT " fp:" PTR_FORMAT, p2i(_sp), p2i(_unextended_sp), p2i(_fp));
|
||||
}
|
||||
|
||||
@@ -361,20 +361,6 @@ inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
|
||||
*result_adr = obj;
|
||||
}
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
if (_cb == nullptr) return nullptr;
|
||||
if (_cb->oop_maps() != nullptr) {
|
||||
NativePostCallNop* nop = nativePostCallNop_at(_pc);
|
||||
if (nop != nullptr && nop->displacement() != 0) {
|
||||
int slot = ((nop->displacement() >> 24) & 0xff);
|
||||
return _cb->oop_map_for_slot(slot, _pc);
|
||||
}
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline int frame::compiled_frame_stack_argsize() const {
|
||||
assert(cb()->is_compiled(), "");
|
||||
return (cb()->as_compiled_method()->method()->num_stack_arg_slots() * VMRegImpl::stack_slot_size) >> LogBytesPerWord;
|
||||
|
||||
@@ -48,9 +48,12 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||
// PPC64 is not specified as multi-copy-atomic
|
||||
// So we must not #define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line, used to pad data structures.
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 128
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#define SUPPORT_RESERVED_STACK_AREA
|
||||
|
||||
// If UseSIGTRAP is active, we only use the poll bit and no polling page.
|
||||
|
||||
@@ -195,4 +195,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Is SIMD sort supported for this CPU?
|
||||
static bool supports_simd_sort(BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // CPU_PPC_MATCHER_PPC_HPP
|
||||
|
||||
@@ -429,10 +429,6 @@ void NativePostCallNop::make_deopt() {
|
||||
NativeDeoptInstruction::insert(addr_at(0));
|
||||
}
|
||||
|
||||
void NativePostCallNop::patch(jint diff) {
|
||||
// unsupported for now
|
||||
}
|
||||
|
||||
void NativeDeoptInstruction::verify() {
|
||||
}
|
||||
|
||||
|
||||
@@ -508,8 +508,8 @@ class NativeMovRegMem: public NativeInstruction {
|
||||
class NativePostCallNop: public NativeInstruction {
|
||||
public:
|
||||
bool check() const { return is_nop(); }
|
||||
int displacement() const { return 0; }
|
||||
void patch(jint diff);
|
||||
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const { return false; }
|
||||
bool patch(int32_t oopmap_slot, int32_t cb_offset) { return false; }
|
||||
void make_deopt();
|
||||
};
|
||||
|
||||
|
||||
@@ -734,7 +734,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
return align_up(stk, 2);
|
||||
return stk;
|
||||
}
|
||||
|
||||
#if defined(COMPILER1) || defined(COMPILER2)
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
// Override Abstract_VM_Version implementation
|
||||
static void print_platform_virtualization_info(outputStream*);
|
||||
|
||||
// PPC64 supports fast class initialization checks for static methods.
|
||||
// PPC64 supports fast class initialization checks
|
||||
static bool supports_fast_class_init_checks() { return true; }
|
||||
constexpr static bool supports_stack_watermark_barrier() { return true; }
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@@ -506,7 +506,7 @@ public:
|
||||
INSN(sllw, 0b0111011, 0b001, 0b0000000);
|
||||
INSN(sraw, 0b0111011, 0b101, 0b0100000);
|
||||
INSN(srlw, 0b0111011, 0b101, 0b0000000);
|
||||
INSN(mul, 0b0110011, 0b000, 0b0000001);
|
||||
INSN(_mul, 0b0110011, 0b000, 0b0000001);
|
||||
INSN(mulh, 0b0110011, 0b001, 0b0000001);
|
||||
INSN(mulhsu,0b0110011, 0b010, 0b0000001);
|
||||
INSN(mulhu, 0b0110011, 0b011, 0b0000001);
|
||||
@@ -537,9 +537,9 @@ public:
|
||||
}
|
||||
|
||||
INSN(lb, 0b0000011, 0b000);
|
||||
INSN(lbu, 0b0000011, 0b100);
|
||||
INSN(lh, 0b0000011, 0b001);
|
||||
INSN(lhu, 0b0000011, 0b101);
|
||||
INSN(_lbu, 0b0000011, 0b100);
|
||||
INSN(_lh, 0b0000011, 0b001);
|
||||
INSN(_lhu, 0b0000011, 0b101);
|
||||
INSN(_lw, 0b0000011, 0b010);
|
||||
INSN(lwu, 0b0000011, 0b110);
|
||||
INSN(_ld, 0b0000011, 0b011);
|
||||
@@ -609,8 +609,8 @@ public:
|
||||
emit(insn); \
|
||||
} \
|
||||
|
||||
INSN(sb, Register, 0b0100011, 0b000);
|
||||
INSN(sh, Register, 0b0100011, 0b001);
|
||||
INSN(_sb, Register, 0b0100011, 0b000);
|
||||
INSN(_sh, Register, 0b0100011, 0b001);
|
||||
INSN(_sw, Register, 0b0100011, 0b010);
|
||||
INSN(_sd, Register, 0b0100011, 0b011);
|
||||
INSN(fsw, FloatRegister, 0b0100111, 0b010);
|
||||
@@ -758,6 +758,8 @@ enum Aqrl {relaxed = 0b00, rl = 0b01, aq = 0b10, aqrl = 0b11};
|
||||
INSN(amomax_d , 0b0101111, 0b011, 0b10100);
|
||||
INSN(amominu_d, 0b0101111, 0b011, 0b11000);
|
||||
INSN(amomaxu_d, 0b0101111, 0b011, 0b11100);
|
||||
INSN(amocas_w, 0b0101111, 0b010, 0b00101);
|
||||
INSN(amocas_d, 0b0101111, 0b011, 0b00101);
|
||||
#undef INSN
|
||||
|
||||
enum operand_size { int8, int16, int32, uint32, int64 };
|
||||
@@ -1154,10 +1156,8 @@ static Assembler::SEW elemtype_to_sew(BasicType etype) {
|
||||
}
|
||||
|
||||
#define patch_vtype(hsb, lsb, vlmul, vsew, vta, vma, vill) \
|
||||
if (vill == 1) { \
|
||||
guarantee((vlmul | vsew | vta | vma == 0), \
|
||||
"the other bits in vtype shall be zero"); \
|
||||
} \
|
||||
/* If vill then other bits of vtype must be zero. */ \
|
||||
guarantee(!vill, "vill not supported"); \
|
||||
patch((address)&insn, lsb + 2, lsb, vlmul); \
|
||||
patch((address)&insn, lsb + 5, lsb + 3, vsew); \
|
||||
patch((address)&insn, lsb + 6, vta); \
|
||||
@@ -1332,6 +1332,7 @@ enum VectorMask {
|
||||
INSN(vsll_vi, 0b1010111, 0b011, 0b100101);
|
||||
|
||||
// Vector Slide Instructions
|
||||
INSN(vslideup_vi, 0b1010111, 0b011, 0b001110);
|
||||
INSN(vslidedown_vi, 0b1010111, 0b011, 0b001111);
|
||||
|
||||
#undef INSN
|
||||
@@ -1687,7 +1688,6 @@ enum VectorMask {
|
||||
INSN(vmv_v_x, 0b1010111, 0b100, v0, 0b1, 0b010111);
|
||||
|
||||
#undef INSN
|
||||
#undef patch_VArith
|
||||
|
||||
#define INSN(NAME, op, funct13, funct6) \
|
||||
void NAME(VectorRegister Vd, VectorMask vm = unmasked) { \
|
||||
@@ -1729,14 +1729,29 @@ enum Nf {
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
emit(insn)
|
||||
|
||||
#define INSN(NAME, op, lumop, vm, mop, nf) \
|
||||
void NAME(VectorRegister Vd, Register Rs1, uint32_t width = 0, bool mew = false) { \
|
||||
#define INSN(NAME, op, width, lumop, vm, mop, mew, nf) \
|
||||
void NAME(VectorRegister Vd, Register Rs1) { \
|
||||
guarantee(is_uimm3(width), "width is invalid"); \
|
||||
patch_VLdSt(op, Vd, width, Rs1, lumop, vm, mop, mew, nf); \
|
||||
}
|
||||
|
||||
// Vector Load/Store Instructions
|
||||
INSN(vl1re8_v, 0b0000111, 0b01000, 0b1, 0b00, g1);
|
||||
INSN(vl1re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vl1re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vl1re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vl1re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vl2re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vl2re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vl2re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vl2re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vl4re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vl4re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vl4re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vl4re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vl8re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
INSN(vl8re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
INSN(vl8re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
INSN(vl8re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
|
||||
#undef INSN
|
||||
|
||||
@@ -1747,6 +1762,9 @@ enum Nf {
|
||||
|
||||
// Vector Load/Store Instructions
|
||||
INSN(vs1r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vs2r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vs4r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vs8r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
|
||||
#undef INSN
|
||||
|
||||
@@ -1792,9 +1810,11 @@ enum Nf {
|
||||
}
|
||||
|
||||
// Vector unordered indexed load instructions
|
||||
INSN( vluxei8_v, 0b0000111, 0b000, 0b01, 0b0);
|
||||
INSN(vluxei32_v, 0b0000111, 0b110, 0b01, 0b0);
|
||||
|
||||
// Vector unordered indexed store instructions
|
||||
INSN( vsuxei8_v, 0b0100111, 0b000, 0b01, 0b0);
|
||||
INSN(vsuxei32_v, 0b0100111, 0b110, 0b01, 0b0);
|
||||
|
||||
#undef INSN
|
||||
@@ -1818,6 +1838,55 @@ enum Nf {
|
||||
#undef INSN
|
||||
#undef patch_VLdSt
|
||||
|
||||
// ====================================
|
||||
// RISC-V Vector Crypto Extension
|
||||
// ====================================
|
||||
|
||||
#define INSN(NAME, op, funct3, funct6) \
|
||||
void NAME(VectorRegister Vd, VectorRegister Vs2, VectorRegister Vs1, VectorMask vm = unmasked) { \
|
||||
patch_VArith(op, Vd, funct3, Vs1->raw_encoding(), Vs2, vm, funct6); \
|
||||
}
|
||||
|
||||
// Vector Bit-manipulation used in Cryptography (Zvkb) Extension
|
||||
INSN(vandn_vv, 0b1010111, 0b000, 0b000001);
|
||||
INSN(vandn_vx, 0b1010111, 0b100, 0b000001);
|
||||
INSN(vandn_vi, 0b1010111, 0b011, 0b000001);
|
||||
INSN(vclmul_vv, 0b1010111, 0b010, 0b001100);
|
||||
INSN(vclmul_vx, 0b1010111, 0b110, 0b001100);
|
||||
INSN(vclmulh_vv, 0b1010111, 0b010, 0b001101);
|
||||
INSN(vclmulh_vx, 0b1010111, 0b110, 0b001101);
|
||||
INSN(vror_vv, 0b1010111, 0b000, 0b010100);
|
||||
INSN(vror_vx, 0b1010111, 0b100, 0b010100);
|
||||
INSN(vrol_vv, 0b1010111, 0b000, 0b010101);
|
||||
INSN(vrol_vx, 0b1010111, 0b100, 0b010101);
|
||||
|
||||
#undef INSN
|
||||
|
||||
#define INSN(NAME, op, funct3, Vs1, funct6) \
|
||||
void NAME(VectorRegister Vd, VectorRegister Vs2, VectorMask vm = unmasked) { \
|
||||
patch_VArith(op, Vd, funct3, Vs1, Vs2, vm, funct6); \
|
||||
}
|
||||
|
||||
// Vector Bit-manipulation used in Cryptography (Zvkb) Extension
|
||||
INSN(vbrev8_v, 0b1010111, 0b010, 0b01000, 0b010010);
|
||||
INSN(vrev8_v, 0b1010111, 0b010, 0b01001, 0b010010);
|
||||
|
||||
#undef INSN
|
||||
|
||||
#define INSN(NAME, op, funct3, vm, funct6) \
|
||||
void NAME(VectorRegister Vd, VectorRegister Vs2, VectorRegister Vs1) { \
|
||||
patch_VArith(op, Vd, funct3, Vs1->raw_encoding(), Vs2, vm, funct6); \
|
||||
}
|
||||
|
||||
// Vector SHA-2 Secure Hash (Zvknh[ab]) Extension
|
||||
INSN(vsha2ms_vv, 0b1110111, 0b010, 0b1, 0b101101);
|
||||
INSN(vsha2ch_vv, 0b1110111, 0b010, 0b1, 0b101110);
|
||||
INSN(vsha2cl_vv, 0b1110111, 0b010, 0b1, 0b101111);
|
||||
|
||||
#undef INSN
|
||||
|
||||
#undef patch_VArith
|
||||
|
||||
// ====================================
|
||||
// RISC-V Bit-Manipulation Extension
|
||||
// Currently only support Zba, Zbb and Zbs bitmanip extensions.
|
||||
@@ -1867,9 +1936,9 @@ enum Nf {
|
||||
}
|
||||
|
||||
INSN(rev8, 0b0010011, 0b101, 0b011010111000);
|
||||
INSN(sext_b, 0b0010011, 0b001, 0b011000000100);
|
||||
INSN(sext_h, 0b0010011, 0b001, 0b011000000101);
|
||||
INSN(zext_h, 0b0111011, 0b100, 0b000010000000);
|
||||
INSN(_sext_b, 0b0010011, 0b001, 0b011000000100);
|
||||
INSN(_sext_h, 0b0010011, 0b001, 0b011000000101);
|
||||
INSN(_zext_h, 0b0111011, 0b100, 0b000010000000);
|
||||
INSN(clz, 0b0010011, 0b001, 0b011000000000);
|
||||
INSN(clzw, 0b0011011, 0b001, 0b011000000000);
|
||||
INSN(ctz, 0b0010011, 0b001, 0b011000000001);
|
||||
@@ -2581,6 +2650,15 @@ public:
|
||||
return UseRVC && in_compressible_region();
|
||||
}
|
||||
|
||||
bool do_compress_zcb(Register reg1 = noreg, Register reg2 = noreg) const {
|
||||
return do_compress() && VM_Version::ext_Zcb.enabled() &&
|
||||
(reg1 == noreg || reg1->is_compressed_valid()) && (reg2 == noreg || reg2->is_compressed_valid());
|
||||
}
|
||||
|
||||
bool do_compress_zcb_zbb(Register reg1 = noreg, Register reg2 = noreg) const {
|
||||
return do_compress_zcb(reg1, reg2) && UseZbb;
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
// Load/store register
|
||||
// --------------------------
|
||||
@@ -2915,6 +2993,238 @@ public:
|
||||
|
||||
#undef INSN
|
||||
|
||||
// -------------- ZCB Instruction Definitions --------------
|
||||
// Zcb additional C instructions
|
||||
private:
|
||||
// Format CLH, c.lh/c.lhu
|
||||
template <bool Unsigned>
|
||||
void c_lh_if(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
|
||||
assert_cond(uimm == 0 || uimm == 2);
|
||||
assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b00);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
|
||||
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
|
||||
c_patch((address)&insn, 6, 6, Unsigned ? 0 : 1);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b001);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
template <bool Unsigned>
|
||||
void lh_c_mux(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
|
||||
if (do_compress_zcb(Rd_Rs2, Rs1) &&
|
||||
(uimm == 0 || uimm == 2)) {
|
||||
c_lh_if<Unsigned>(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
if (Unsigned) {
|
||||
_lhu(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
_lh(Rd_Rs2, Rs1, uimm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format CU, c.[sz]ext.*, c.not
|
||||
template <uint8_t InstructionType>
|
||||
void c_u_if(Register Rs1) {
|
||||
assert_cond(do_compress_zcb(Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b01);
|
||||
c_patch((address)&insn, 4, 2, InstructionType);
|
||||
c_patch((address)&insn, 6, 5, 0b11);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b111);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Prerequisites: Zcb
|
||||
void c_lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_if<false>(Rd_Rs2, Rs1, uimm); }
|
||||
void lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_c_mux<false>(Rd_Rs2, Rs1, uimm); }
|
||||
|
||||
// Prerequisites: Zcb
|
||||
void c_lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_if<true>(Rd_Rs2, Rs1, uimm); }
|
||||
void lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_c_mux<true>(Rd_Rs2, Rs1, uimm); }
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CLB, single instruction
|
||||
void c_lbu(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
|
||||
assert_cond(uimm <= 3);
|
||||
assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b00);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
|
||||
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
|
||||
c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b000);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
void lbu(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
|
||||
if (do_compress_zcb(Rd_Rs2, Rs1) &&
|
||||
uimm >= 0 && uimm <= 3) {
|
||||
c_lbu(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
_lbu(Rd_Rs2, Rs1, uimm);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CSB, single instruction
|
||||
void c_sb(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
|
||||
assert_cond(uimm <= 3);
|
||||
assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b00);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
|
||||
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
|
||||
c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b010);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
void sb(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
|
||||
if (do_compress_zcb(Rd_Rs2, Rs1) &&
|
||||
uimm >= 0 && uimm <= 3) {
|
||||
c_sb(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
_sb(Rd_Rs2, Rs1, uimm);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CSH, single instruction
|
||||
void c_sh(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
|
||||
assert_cond(uimm == 0 || uimm == 2);
|
||||
assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b00);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
|
||||
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
|
||||
c_patch((address)&insn, 6, 6, 0);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b011);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
void sh(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
|
||||
if (do_compress_zcb(Rd_Rs2, Rs1) &&
|
||||
(uimm == 0 || uimm == 2)) {
|
||||
c_sh(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
_sh(Rd_Rs2, Rs1, uimm);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CS
|
||||
void c_zext_b(Register Rs1) {
|
||||
assert_cond(do_compress_zcb(Rs1));
|
||||
c_u_if<0b000>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zbb
|
||||
void sext_b(Register Rd_Rs2, Register Rs1) {
|
||||
assert_cond(UseZbb);
|
||||
if (do_compress_zcb_zbb(Rd_Rs2, Rs1) && (Rd_Rs2 == Rs1)) {
|
||||
c_sext_b(Rd_Rs2);
|
||||
} else {
|
||||
_sext_b(Rd_Rs2, Rs1);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb, Zbb
|
||||
// Format CS
|
||||
void c_sext_b(Register Rs1) {
|
||||
c_u_if<0b001>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zbb
|
||||
void zext_h(Register Rd_Rs2, Register Rs1) {
|
||||
assert_cond(UseZbb);
|
||||
if (do_compress_zcb_zbb(Rd_Rs2, Rs1) && (Rd_Rs2 == Rs1)) {
|
||||
c_zext_h(Rd_Rs2);
|
||||
} else {
|
||||
_zext_h(Rd_Rs2, Rs1);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb, Zbb
|
||||
// Format CS
|
||||
void c_zext_h(Register Rs1) {
|
||||
c_u_if<0b010>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zbb
|
||||
void sext_h(Register Rd_Rs2, Register Rs1) {
|
||||
assert_cond(UseZbb);
|
||||
if (do_compress_zcb_zbb(Rd_Rs2, Rs1) && (Rd_Rs2 == Rs1)) {
|
||||
c_sext_h(Rd_Rs2);
|
||||
} else {
|
||||
_sext_h(Rd_Rs2, Rs1);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb, Zbb
|
||||
// Format CS
|
||||
void c_sext_h(Register Rs1) {
|
||||
c_u_if<0b011>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb, Zba
|
||||
// Format CS
|
||||
void c_zext_w(Register Rs1) {
|
||||
c_u_if<0b100>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CS
|
||||
void c_not(Register Rs1) {
|
||||
c_u_if<0b101>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb (M or Zmmul)
|
||||
// Format CA, c.mul
|
||||
void c_mul(Register Rd_Rs1, Register Rs2) {
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b01);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rs2);
|
||||
c_patch((address)&insn, 6, 5, 0b10);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rd_Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b111);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
void mul(Register Rd, Register Rs1, Register Rs2) {
|
||||
if (Rd != Rs1 && Rd != Rs2) {
|
||||
// Three registers needed without a mv, emit uncompressed
|
||||
_mul(Rd, Rs1, Rs2);
|
||||
return;
|
||||
}
|
||||
|
||||
// Rd is either Rs1 or Rs2
|
||||
if (!do_compress_zcb(Rs2, Rs1)) {
|
||||
_mul(Rd, Rs1, Rs2);
|
||||
} else {
|
||||
if (Rd == Rs2) {
|
||||
Rs2 = Rs1;
|
||||
} else {
|
||||
assert(Rd == Rs1, "must be");
|
||||
}
|
||||
c_mul(Rd, Rs2);
|
||||
}
|
||||
}
|
||||
|
||||
// Stack overflow checking
|
||||
virtual void bang_stack_with_offset(int offset) { Unimplemented(); }
|
||||
|
||||
@@ -2940,6 +3250,17 @@ public:
|
||||
return uabs(target - branch) < branch_range;
|
||||
}
|
||||
|
||||
// Decode the given instruction, checking if it's a 16-bit compressed
|
||||
// instruction and return the address of the next instruction.
|
||||
static address locate_next_instruction(address inst) {
|
||||
// Instruction wider than 16 bits has the two least-significant bits set.
|
||||
if ((0x3 & *inst) == 0x3) {
|
||||
return inst + instruction_size;
|
||||
} else {
|
||||
return inst + compressed_instruction_size;
|
||||
}
|
||||
}
|
||||
|
||||
Assembler(CodeBuffer* code) : AbstractAssembler(code), _in_compressible_region(true) {}
|
||||
};
|
||||
|
||||
|
||||
@@ -1459,6 +1459,112 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2,
|
||||
BLOCK_COMMENT("} string_equals");
|
||||
}
|
||||
|
||||
// jdk.internal.util.ArraysSupport.vectorizedHashCode
|
||||
void C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register result,
|
||||
Register tmp1, Register tmp2, Register tmp3,
|
||||
Register tmp4, Register tmp5, Register tmp6,
|
||||
BasicType eltype)
|
||||
{
|
||||
assert_different_registers(ary, cnt, result, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, t0, t1);
|
||||
|
||||
const int elsize = arrays_hashcode_elsize(eltype);
|
||||
const int chunks_end_shift = exact_log2(elsize);
|
||||
|
||||
switch (eltype) {
|
||||
case T_BOOLEAN: BLOCK_COMMENT("arrays_hashcode(unsigned byte) {"); break;
|
||||
case T_CHAR: BLOCK_COMMENT("arrays_hashcode(char) {"); break;
|
||||
case T_BYTE: BLOCK_COMMENT("arrays_hashcode(byte) {"); break;
|
||||
case T_SHORT: BLOCK_COMMENT("arrays_hashcode(short) {"); break;
|
||||
case T_INT: BLOCK_COMMENT("arrays_hashcode(int) {"); break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
const int stride = 4;
|
||||
const Register pow31_4 = tmp1;
|
||||
const Register pow31_3 = tmp2;
|
||||
const Register pow31_2 = tmp3;
|
||||
const Register chunks = tmp4;
|
||||
const Register chunks_end = chunks;
|
||||
|
||||
Label DONE, TAIL, TAIL_LOOP, WIDE_LOOP;
|
||||
|
||||
// result has a value initially
|
||||
|
||||
beqz(cnt, DONE);
|
||||
|
||||
andi(chunks, cnt, ~(stride-1));
|
||||
beqz(chunks, TAIL);
|
||||
|
||||
mv(pow31_4, 923521); // [31^^4]
|
||||
mv(pow31_3, 29791); // [31^^3]
|
||||
mv(pow31_2, 961); // [31^^2]
|
||||
|
||||
slli(chunks_end, chunks, chunks_end_shift);
|
||||
add(chunks_end, ary, chunks_end);
|
||||
andi(cnt, cnt, stride-1); // don't forget about tail!
|
||||
|
||||
bind(WIDE_LOOP);
|
||||
mulw(result, result, pow31_4); // 31^^4 * h
|
||||
arrays_hashcode_elload(t0, Address(ary, 0 * elsize), eltype);
|
||||
arrays_hashcode_elload(t1, Address(ary, 1 * elsize), eltype);
|
||||
arrays_hashcode_elload(tmp5, Address(ary, 2 * elsize), eltype);
|
||||
arrays_hashcode_elload(tmp6, Address(ary, 3 * elsize), eltype);
|
||||
mulw(t0, t0, pow31_3); // 31^^3 * ary[i+0]
|
||||
addw(result, result, t0);
|
||||
mulw(t1, t1, pow31_2); // 31^^2 * ary[i+1]
|
||||
addw(result, result, t1);
|
||||
slli(t0, tmp5, 5); // optimize 31^^1 * ary[i+2]
|
||||
subw(tmp5, t0, tmp5); // with ary[i+2]<<5 - ary[i+2]
|
||||
addw(result, result, tmp5);
|
||||
addw(result, result, tmp6); // 31^^4 * h + 31^^3 * ary[i+0] + 31^^2 * ary[i+1]
|
||||
// + 31^^1 * ary[i+2] + 31^^0 * ary[i+3]
|
||||
addi(ary, ary, elsize * stride);
|
||||
bne(ary, chunks_end, WIDE_LOOP);
|
||||
beqz(cnt, DONE);
|
||||
|
||||
bind(TAIL);
|
||||
slli(chunks_end, cnt, chunks_end_shift);
|
||||
add(chunks_end, ary, chunks_end);
|
||||
|
||||
bind(TAIL_LOOP);
|
||||
arrays_hashcode_elload(t0, Address(ary), eltype);
|
||||
slli(t1, result, 5); // optimize 31 * result
|
||||
subw(result, t1, result); // with result<<5 - result
|
||||
addw(result, result, t0);
|
||||
addi(ary, ary, elsize);
|
||||
bne(ary, chunks_end, TAIL_LOOP);
|
||||
|
||||
bind(DONE);
|
||||
BLOCK_COMMENT("} // arrays_hashcode");
|
||||
}
|
||||
|
||||
int C2_MacroAssembler::arrays_hashcode_elsize(BasicType eltype) {
|
||||
switch (eltype) {
|
||||
case T_BOOLEAN: return sizeof(jboolean);
|
||||
case T_BYTE: return sizeof(jbyte);
|
||||
case T_SHORT: return sizeof(jshort);
|
||||
case T_CHAR: return sizeof(jchar);
|
||||
case T_INT: return sizeof(jint);
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::arrays_hashcode_elload(Register dst, Address src, BasicType eltype) {
|
||||
switch (eltype) {
|
||||
// T_BOOLEAN used as surrogate for unsigned byte
|
||||
case T_BOOLEAN: lbu(dst, src); break;
|
||||
case T_BYTE: lb(dst, src); break;
|
||||
case T_SHORT: lh(dst, src); break;
|
||||
case T_CHAR: lhu(dst, src); break;
|
||||
case T_INT: lw(dst, src); break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (Assembler::*conditional_branch_insn)(Register op1, Register op2, Label& label, bool is_far);
|
||||
typedef void (MacroAssembler::*float_conditional_branch_insn)(FloatRegister op1, FloatRegister op2, Label& label,
|
||||
bool is_far, bool is_unordered);
|
||||
|
||||
@@ -82,6 +82,15 @@
|
||||
Register result, Register cnt1,
|
||||
int elem_size);
|
||||
|
||||
void arrays_hashcode(Register ary, Register cnt, Register result,
|
||||
Register tmp1, Register tmp2,
|
||||
Register tmp3, Register tmp4,
|
||||
Register tmp5, Register tmp6,
|
||||
BasicType eltype);
|
||||
// helper function for arrays_hashcode
|
||||
int arrays_hashcode_elsize(BasicType eltype);
|
||||
void arrays_hashcode_elload(Register dst, Address src, BasicType eltype);
|
||||
|
||||
void string_equals(Register r1, Register r2,
|
||||
Register result, Register cnt1,
|
||||
int elem_size);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "code/compiledIC.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
@@ -88,9 +89,9 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
address stub = find_stub();
|
||||
guarantee(stub != nullptr, "stub not found");
|
||||
|
||||
if (TraceICs) {
|
||||
{
|
||||
ResourceMark rm;
|
||||
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
p2i(instruction_address()),
|
||||
callee->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
@@ -189,8 +189,6 @@
|
||||
static void verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp);
|
||||
#endif
|
||||
|
||||
const ImmutableOopMap* get_oop_map() const;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@@ -186,7 +186,7 @@ inline bool frame::equal(frame other) const {
|
||||
unextended_sp() == other.unextended_sp() &&
|
||||
fp() == other.fp() &&
|
||||
pc() == other.pc();
|
||||
assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
|
||||
assert(!ret || (cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -345,20 +345,6 @@ inline int frame::sender_sp_ret_address_offset() {
|
||||
return frame::sender_sp_offset - frame::return_addr_offset;
|
||||
}
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
if (_cb == nullptr) return nullptr;
|
||||
if (_cb->oop_maps() != nullptr) {
|
||||
NativePostCallNop* nop = nativePostCallNop_at(_pc);
|
||||
if (nop != nullptr && nop->displacement() != 0) {
|
||||
int slot = ((nop->displacement() >> 24) & 0xff);
|
||||
return _cb->oop_map_for_slot(slot, _pc);
|
||||
}
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::sender
|
||||
frame frame::sender(RegisterMap* map) const {
|
||||
|
||||
@@ -52,11 +52,11 @@ static void x_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node
|
||||
%}
|
||||
|
||||
// Load Pointer
|
||||
instruct xLoadP(iRegPNoSp dst, memory mem)
|
||||
instruct xLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(UseZGC && !ZGenerational && (n->as_Load()->barrier_data() != 0));
|
||||
effect(TEMP dst);
|
||||
effect(TEMP dst, TEMP tmp);
|
||||
|
||||
ins_cost(4 * DEFAULT_COST);
|
||||
|
||||
@@ -65,17 +65,17 @@ instruct xLoadP(iRegPNoSp dst, memory mem)
|
||||
ins_encode %{
|
||||
const Address ref_addr (as_Register($mem$$base), $mem$$disp);
|
||||
__ ld($dst$$Register, ref_addr);
|
||||
x_load_barrier(_masm, this, ref_addr, $dst$$Register, t0 /* tmp */, barrier_data());
|
||||
x_load_barrier(_masm, this, ref_addr, $dst$$Register, $tmp$$Register /* tmp */, barrier_data());
|
||||
%}
|
||||
|
||||
ins_pipe(iload_reg_mem);
|
||||
%}
|
||||
|
||||
instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong);
|
||||
effect(KILL cr, TEMP_DEF res);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -86,17 +86,15 @@ instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
|
||||
Label failed;
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register,
|
||||
true /* result_as_bool */);
|
||||
__ beqz($res$$Register, failed);
|
||||
__ mv(t0, $oldval$$Register);
|
||||
__ bind(failed);
|
||||
Assembler::relaxed /* acquire */, Assembler::rl /* release */, $tmp$$Register);
|
||||
__ sub(t0, $tmp$$Register, $oldval$$Register);
|
||||
__ seqz($res$$Register, t0);
|
||||
if (barrier_data() != XLoadBarrierElided) {
|
||||
Label good;
|
||||
__ ld(t1, Address(xthread, XThreadLocalData::address_bad_mask_offset()), t1 /* tmp */);
|
||||
__ andr(t1, t1, t0);
|
||||
__ beqz(t1, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), t0 /* ref */, t1 /* tmp */);
|
||||
__ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(t0, t0, $tmp$$Register);
|
||||
__ beqz(t0, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $tmp$$Register /* ref */, $res$$Register /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register,
|
||||
true /* result_as_bool */);
|
||||
@@ -107,11 +105,11 @@ instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == XLoadBarrierStrong));
|
||||
effect(KILL cr, TEMP_DEF res);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -122,17 +120,15 @@ instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
|
||||
Label failed;
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register,
|
||||
true /* result_as_bool */);
|
||||
__ beqz($res$$Register, failed);
|
||||
__ mv(t0, $oldval$$Register);
|
||||
__ bind(failed);
|
||||
Assembler::aq /* acquire */, Assembler::rl /* release */, $tmp$$Register);
|
||||
__ sub(t0, $tmp$$Register, $oldval$$Register);
|
||||
__ seqz($res$$Register, t0);
|
||||
if (barrier_data() != XLoadBarrierElided) {
|
||||
Label good;
|
||||
__ ld(t1, Address(xthread, XThreadLocalData::address_bad_mask_offset()), t1 /* tmp */);
|
||||
__ andr(t1, t1, t0);
|
||||
__ beqz(t1, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), t0 /* ref */, t1 /* tmp */);
|
||||
__ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(t0, t0, $tmp$$Register);
|
||||
__ beqz(t0, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $tmp$$Register /* ref */, $res$$Register /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register,
|
||||
true /* result_as_bool */);
|
||||
@@ -143,10 +139,10 @@ instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{
|
||||
instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong);
|
||||
effect(TEMP_DEF res);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -161,7 +157,7 @@ instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
__ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(t0, t0, $res$$Register);
|
||||
__ beqz(t0, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, t0 /* tmp */);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, $tmp$$Register /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register);
|
||||
__ bind(good);
|
||||
@@ -171,10 +167,10 @@ instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{
|
||||
instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong);
|
||||
effect(TEMP_DEF res);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -189,7 +185,7 @@ instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
__ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(t0, t0, $res$$Register);
|
||||
__ beqz(t0, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, t0 /* tmp */);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, $tmp$$Register /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register);
|
||||
__ bind(good);
|
||||
@@ -199,10 +195,10 @@ instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -210,16 +206,16 @@ instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
|
||||
ins_encode %{
|
||||
__ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
|
||||
x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data());
|
||||
x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, $tmp$$Register /* tmp */, barrier_data());
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() != 0));
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
|
||||
@@ -227,7 +223,7 @@ instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr)
|
||||
|
||||
ins_encode %{
|
||||
__ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
|
||||
x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data());
|
||||
x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, $tmp$$Register /* tmp */, barrier_data());
|
||||
%}
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
@@ -79,7 +79,7 @@ static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address
|
||||
|
||||
static void z_store_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register rnew_zaddress, Register rnew_zpointer, Register tmp, bool is_atomic) {
|
||||
if (node->barrier_data() == ZBarrierElided) {
|
||||
z_color(_masm, node, rnew_zpointer, rnew_zaddress, t0);
|
||||
z_color(_masm, node, rnew_zpointer, rnew_zaddress, tmp);
|
||||
} else {
|
||||
bool is_native = (node->barrier_data() & ZBarrierNative) != 0;
|
||||
ZStoreBarrierStubC2* const stub = ZStoreBarrierStubC2::create(node, ref_addr, rnew_zaddress, rnew_zpointer, is_native, is_atomic);
|
||||
@@ -90,11 +90,11 @@ static void z_store_barrier(MacroAssembler& _masm, const MachNode* node, Address
|
||||
%}
|
||||
|
||||
// Load Pointer
|
||||
instruct zLoadP(iRegPNoSp dst, memory mem)
|
||||
instruct zLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(UseZGC && ZGenerational && n->as_Load()->barrier_data() != 0);
|
||||
effect(TEMP dst);
|
||||
effect(TEMP dst, TEMP tmp);
|
||||
|
||||
ins_cost(4 * DEFAULT_COST);
|
||||
|
||||
@@ -103,34 +103,35 @@ instruct zLoadP(iRegPNoSp dst, memory mem)
|
||||
ins_encode %{
|
||||
const Address ref_addr(as_Register($mem$$base), $mem$$disp);
|
||||
__ ld($dst$$Register, ref_addr);
|
||||
z_load_barrier(_masm, this, ref_addr, $dst$$Register, t0);
|
||||
z_load_barrier(_masm, this, ref_addr, $dst$$Register, $tmp$$Register);
|
||||
%}
|
||||
|
||||
ins_pipe(iload_reg_mem);
|
||||
%}
|
||||
|
||||
// Store Pointer
|
||||
instruct zStoreP(memory mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
|
||||
instruct zStoreP(memory mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2)
|
||||
%{
|
||||
predicate(UseZGC && ZGenerational && n->as_Store()->barrier_data() != 0);
|
||||
match(Set mem (StoreP mem src));
|
||||
effect(TEMP tmp, KILL cr);
|
||||
effect(TEMP tmp1, TEMP tmp2);
|
||||
|
||||
ins_cost(125); // XXX
|
||||
format %{ "sd $mem, $src\t# ptr" %}
|
||||
ins_encode %{
|
||||
const Address ref_addr(as_Register($mem$$base), $mem$$disp);
|
||||
z_store_barrier(_masm, this, ref_addr, $src$$Register, $tmp$$Register, t1, false /* is_atomic */);
|
||||
__ sd($tmp$$Register, ref_addr);
|
||||
z_store_barrier(_masm, this, ref_addr, $src$$Register, $tmp1$$Register, $tmp2$$Register, false /* is_atomic */);
|
||||
__ sd($tmp1$$Register, ref_addr);
|
||||
%}
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{
|
||||
instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -140,19 +141,20 @@ instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
|
||||
ins_encode %{
|
||||
guarantee($mem$$disp == 0, "impossible encoding");
|
||||
Address ref_addr($mem$$Register);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, $tmp1$$Register);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, $tmp1$$Register, true /* is_atomic */);
|
||||
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, true /* result_as_bool */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{
|
||||
instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -162,18 +164,19 @@ instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
|
||||
ins_encode %{
|
||||
guarantee($mem$$disp == 0, "impossible encoding");
|
||||
Address ref_addr($mem$$Register);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, $tmp1$$Register);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, $tmp1$$Register, true /* is_atomic */);
|
||||
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, true /* result_as_bool */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{
|
||||
instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -182,8 +185,8 @@ instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
ins_encode %{
|
||||
guarantee($mem$$disp == 0, "impossible encoding");
|
||||
Address ref_addr($mem$$Register);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, $tmp1$$Register);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, $tmp1$$Register, true /* is_atomic */);
|
||||
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register);
|
||||
z_uncolor(_masm, this, $res$$Register);
|
||||
%}
|
||||
@@ -191,10 +194,11 @@ instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{
|
||||
instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -203,8 +207,8 @@ instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
ins_encode %{
|
||||
guarantee($mem$$disp == 0, "impossible encoding");
|
||||
Address ref_addr($mem$$Register);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, $tmp1$$Register);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, $tmp1$$Register, true /* is_atomic */);
|
||||
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register);
|
||||
z_uncolor(_masm, this, $res$$Register);
|
||||
%}
|
||||
@@ -212,17 +216,17 @@ instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
format %{ "atomic_xchg $prev, $newv, [$mem], #@zGetAndSetP" %}
|
||||
|
||||
ins_encode %{
|
||||
z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, t1, true /* is_atomic */);
|
||||
z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, $tmp$$Register, true /* is_atomic */);
|
||||
__ atomic_xchg($prev$$Register, $prev$$Register, $mem$$Register);
|
||||
z_uncolor(_masm, this, $prev$$Register);
|
||||
%}
|
||||
@@ -230,17 +234,17 @@ instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
format %{ "atomic_xchg_acq $prev, $newv, [$mem], #@zGetAndSetPAcq" %}
|
||||
|
||||
ins_encode %{
|
||||
z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, t1, true /* is_atomic */);
|
||||
z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, $tmp$$Register, true /* is_atomic */);
|
||||
__ atomic_xchgal($prev$$Register, $prev$$Register, $mem$$Register);
|
||||
z_uncolor(_masm, this, $prev$$Register);
|
||||
%}
|
||||
|
||||
@@ -50,6 +50,10 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
|
||||
#define USE_POINTERS_TO_REGISTER_IMPL_ARRAY
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#endif // CPU_RISCV_GLOBALDEFINITIONS_RISCV_HPP
|
||||
|
||||
@@ -105,6 +105,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
|
||||
product(bool, UseZba, false, "Use Zba instructions") \
|
||||
product(bool, UseZbb, false, "Use Zbb instructions") \
|
||||
product(bool, UseZbs, false, "Use Zbs instructions") \
|
||||
product(bool, UseZacas, false, EXPERIMENTAL, "Use Zacas instructions") \
|
||||
product(bool, UseZic64b, false, EXPERIMENTAL, "Use Zic64b instructions") \
|
||||
product(bool, UseZicbom, false, EXPERIMENTAL, "Use Zicbom instructions") \
|
||||
product(bool, UseZicbop, false, EXPERIMENTAL, "Use Zicbop instructions") \
|
||||
@@ -112,6 +113,8 @@ define_pd_global(intx, InlineSmallCode, 1000);
|
||||
product(bool, UseZtso, false, EXPERIMENTAL, "Assume Ztso memory model") \
|
||||
product(bool, UseZihintpause, false, EXPERIMENTAL, \
|
||||
"Use Zihintpause instructions") \
|
||||
product(bool, UseZvkn, false, EXPERIMENTAL, \
|
||||
"Use Zvkn group extension, Zvkned, Zvknhb, Zvkb, Zvkt") \
|
||||
product(bool, UseRVVForBigIntegerShiftIntrinsics, true, \
|
||||
"Use RVV instructions for left/right shift of BigInteger")
|
||||
|
||||
|
||||
@@ -777,7 +777,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
|
||||
assert(lock_offset == 0,
|
||||
"displached header must be first word in BasicObjectLock");
|
||||
|
||||
cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, t0, count, /*fallthrough*/nullptr);
|
||||
cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, tmp, count, /*fallthrough*/nullptr);
|
||||
|
||||
// Test if the oopMark is an obvious stack pointer, i.e.,
|
||||
// 1) (mark & 7) == 0, and
|
||||
@@ -891,7 +891,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
|
||||
beqz(header_reg, count);
|
||||
|
||||
// Atomic swap back the old header
|
||||
cmpxchg_obj_header(swap_reg, header_reg, obj_reg, t0, count, /*fallthrough*/nullptr);
|
||||
cmpxchg_obj_header(swap_reg, header_reg, obj_reg, tmp_reg, count, /*fallthrough*/nullptr);
|
||||
}
|
||||
|
||||
// Call the runtime routine for slow case.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@@ -2725,27 +2725,36 @@ void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool acqui
|
||||
|
||||
void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp,
|
||||
Label &succeed, Label *fail) {
|
||||
assert_different_registers(addr, tmp);
|
||||
assert_different_registers(newv, tmp);
|
||||
assert_different_registers(oldv, tmp);
|
||||
assert_different_registers(addr, tmp, t0);
|
||||
assert_different_registers(newv, tmp, t0);
|
||||
assert_different_registers(oldv, tmp, t0);
|
||||
|
||||
// oldv holds comparison value
|
||||
// newv holds value to write in exchange
|
||||
// addr identifies memory word to compare against/update
|
||||
Label retry_load, nope;
|
||||
bind(retry_load);
|
||||
// Load reserved from the memory location
|
||||
load_reserved(tmp, addr, int64, Assembler::aqrl);
|
||||
// Fail and exit if it is not what we expect
|
||||
bne(tmp, oldv, nope);
|
||||
// If the store conditional succeeds, tmp will be zero
|
||||
store_conditional(tmp, newv, addr, int64, Assembler::rl);
|
||||
beqz(tmp, succeed);
|
||||
// Retry only when the store conditional failed
|
||||
j(retry_load);
|
||||
if (UseZacas) {
|
||||
mv(tmp, oldv);
|
||||
atomic_cas(tmp, newv, addr, Assembler::int64, Assembler::aq, Assembler::rl);
|
||||
beq(tmp, oldv, succeed);
|
||||
} else {
|
||||
Label retry_load, nope;
|
||||
bind(retry_load);
|
||||
// Load reserved from the memory location
|
||||
load_reserved(tmp, addr, int64, Assembler::aqrl);
|
||||
// Fail and exit if it is not what we expect
|
||||
bne(tmp, oldv, nope);
|
||||
// If the store conditional succeeds, tmp will be zero
|
||||
store_conditional(tmp, newv, addr, int64, Assembler::rl);
|
||||
beqz(tmp, succeed);
|
||||
// Retry only when the store conditional failed
|
||||
j(retry_load);
|
||||
|
||||
bind(nope);
|
||||
bind(nope);
|
||||
}
|
||||
|
||||
// neither amocas nor lr/sc have an implied barrier in the failing case
|
||||
membar(AnyAny);
|
||||
|
||||
mv(oldv, tmp);
|
||||
if (fail != nullptr) {
|
||||
j(*fail);
|
||||
@@ -2771,7 +2780,7 @@ void MacroAssembler::load_reserved(Register dst,
|
||||
break;
|
||||
case uint32:
|
||||
lr_w(dst, addr, acquire);
|
||||
zero_extend(t0, t0, 32);
|
||||
zero_extend(dst, dst, 32);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@@ -2819,7 +2828,7 @@ void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expecte
|
||||
}
|
||||
sll(mask, mask, shift);
|
||||
|
||||
xori(not_mask, mask, -1);
|
||||
notr(not_mask, mask);
|
||||
|
||||
sll(expected, expected, shift);
|
||||
andr(expected, expected, mask);
|
||||
@@ -2829,7 +2838,7 @@ void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expecte
|
||||
}
|
||||
|
||||
// cmpxchg_narrow_value will kill t0, t1, expected, new_val and tmps.
|
||||
// It's designed to implement compare and swap byte/boolean/char/short by lr.w/sc.w,
|
||||
// It's designed to implement compare and swap byte/boolean/char/short by lr.w/sc.w or amocas.w,
|
||||
// which are forced to work with 4-byte aligned address.
|
||||
void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected,
|
||||
Register new_val,
|
||||
@@ -2844,14 +2853,29 @@ void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected,
|
||||
Label retry, fail, done;
|
||||
|
||||
bind(retry);
|
||||
lr_w(old, aligned_addr, acquire);
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
sc_w(tmp, tmp, aligned_addr, release);
|
||||
bnez(tmp, retry);
|
||||
if (UseZacas) {
|
||||
lw(old, aligned_addr);
|
||||
|
||||
// if old & mask != expected
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
|
||||
atomic_cas(old, tmp, aligned_addr, operand_size::int32, acquire, release);
|
||||
bne(tmp, old, retry);
|
||||
} else {
|
||||
lr_w(old, aligned_addr, acquire);
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
sc_w(tmp, tmp, aligned_addr, release);
|
||||
bnez(tmp, retry);
|
||||
}
|
||||
|
||||
if (result_as_bool) {
|
||||
mv(result, 1);
|
||||
@@ -2891,14 +2915,28 @@ void MacroAssembler::weak_cmpxchg_narrow_value(Register addr, Register expected,
|
||||
|
||||
Label fail, done;
|
||||
|
||||
lr_w(old, aligned_addr, acquire);
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
if (UseZacas) {
|
||||
lw(old, aligned_addr);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
sc_w(tmp, tmp, aligned_addr, release);
|
||||
bnez(tmp, fail);
|
||||
// if old & mask != expected
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
|
||||
atomic_cas(tmp, new_val, addr, operand_size::int32, acquire, release);
|
||||
bne(tmp, old, fail);
|
||||
} else {
|
||||
lr_w(old, aligned_addr, acquire);
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
sc_w(tmp, tmp, aligned_addr, release);
|
||||
bnez(tmp, fail);
|
||||
}
|
||||
|
||||
// Success
|
||||
mv(result, 1);
|
||||
@@ -2921,6 +2959,19 @@ void MacroAssembler::cmpxchg(Register addr, Register expected,
|
||||
assert_different_registers(expected, t0);
|
||||
assert_different_registers(new_val, t0);
|
||||
|
||||
if (UseZacas) {
|
||||
if (result_as_bool) {
|
||||
mv(t0, expected);
|
||||
atomic_cas(t0, new_val, addr, size, acquire, release);
|
||||
xorr(t0, t0, expected);
|
||||
seqz(result, t0);
|
||||
} else {
|
||||
mv(result, expected);
|
||||
atomic_cas(result, new_val, addr, size, acquire, release);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Label retry_load, done, ne_done;
|
||||
bind(retry_load);
|
||||
load_reserved(t0, addr, size, acquire);
|
||||
@@ -2952,6 +3003,11 @@ void MacroAssembler::cmpxchg_weak(Register addr, Register expected,
|
||||
enum operand_size size,
|
||||
Assembler::Aqrl acquire, Assembler::Aqrl release,
|
||||
Register result) {
|
||||
if (UseZacas) {
|
||||
cmpxchg(addr, expected, new_val, size, acquire, release, result, true);
|
||||
return;
|
||||
}
|
||||
|
||||
assert_different_registers(addr, t0);
|
||||
assert_different_registers(expected, t0);
|
||||
assert_different_registers(new_val, t0);
|
||||
@@ -3018,6 +3074,89 @@ ATOMIC_XCHGU(xchgalwu, xchgalw)
|
||||
|
||||
#undef ATOMIC_XCHGU
|
||||
|
||||
#define ATOMIC_CAS(OP, AOP, ACQUIRE, RELEASE) \
|
||||
void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) { \
|
||||
assert(UseZacas, "invariant"); \
|
||||
prev = prev->is_valid() ? prev : zr; \
|
||||
AOP(prev, addr, newv, (Assembler::Aqrl)(ACQUIRE | RELEASE)); \
|
||||
return; \
|
||||
}
|
||||
|
||||
ATOMIC_CAS(cas, amocas_d, Assembler::relaxed, Assembler::relaxed)
|
||||
ATOMIC_CAS(casw, amocas_w, Assembler::relaxed, Assembler::relaxed)
|
||||
ATOMIC_CAS(casl, amocas_d, Assembler::relaxed, Assembler::rl)
|
||||
ATOMIC_CAS(caslw, amocas_w, Assembler::relaxed, Assembler::rl)
|
||||
ATOMIC_CAS(casal, amocas_d, Assembler::aq, Assembler::rl)
|
||||
ATOMIC_CAS(casalw, amocas_w, Assembler::aq, Assembler::rl)
|
||||
|
||||
#undef ATOMIC_CAS
|
||||
|
||||
#define ATOMIC_CASU(OP1, OP2) \
|
||||
void MacroAssembler::atomic_##OP1(Register prev, Register newv, Register addr) { \
|
||||
atomic_##OP2(prev, newv, addr); \
|
||||
zero_extend(prev, prev, 32); \
|
||||
return; \
|
||||
}
|
||||
|
||||
ATOMIC_CASU(caswu, casw)
|
||||
ATOMIC_CASU(caslwu, caslw)
|
||||
ATOMIC_CASU(casalwu, casalw)
|
||||
|
||||
#undef ATOMIC_CASU
|
||||
|
||||
void MacroAssembler::atomic_cas(
|
||||
Register prev, Register newv, Register addr, enum operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release) {
|
||||
switch (size) {
|
||||
case int64:
|
||||
switch ((Assembler::Aqrl)(acquire | release)) {
|
||||
case Assembler::relaxed:
|
||||
atomic_cas(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::rl:
|
||||
atomic_casl(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::aqrl:
|
||||
atomic_casal(prev, newv, addr);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
break;
|
||||
case int32:
|
||||
switch ((Assembler::Aqrl)(acquire | release)) {
|
||||
case Assembler::relaxed:
|
||||
atomic_casw(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::rl:
|
||||
atomic_caslw(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::aqrl:
|
||||
atomic_casalw(prev, newv, addr);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
break;
|
||||
case uint32:
|
||||
switch ((Assembler::Aqrl)(acquire | release)) {
|
||||
case Assembler::relaxed:
|
||||
atomic_caswu(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::rl:
|
||||
atomic_caslwu(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::aqrl:
|
||||
atomic_casalwu(prev, newv, addr);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::far_jump(const Address &entry, Register tmp) {
|
||||
assert(ReservedCodeCacheSize < 4*G, "branch out of range");
|
||||
assert(CodeCache::find_blob(entry.target()) != nullptr,
|
||||
@@ -4342,6 +4481,57 @@ void MacroAssembler::zero_dcache_blocks(Register base, Register cnt, Register tm
|
||||
bge(cnt, tmp1, loop);
|
||||
}
|
||||
|
||||
// java.lang.Math.round(float a)
|
||||
// Returns the closest int to the argument, with ties rounding to positive infinity.
|
||||
void MacroAssembler::java_round_float(Register dst, FloatRegister src, FloatRegister ftmp) {
|
||||
// this instructions calling sequence provides performance improvement on all tested devices;
|
||||
// don't change it without re-verification
|
||||
Label done;
|
||||
mv(t0, jint_cast(0.5f));
|
||||
fmv_w_x(ftmp, t0);
|
||||
|
||||
// dst = 0 if NaN
|
||||
feq_s(t0, src, src); // replacing fclass with feq as performance optimization
|
||||
mv(dst, zr);
|
||||
beqz(t0, done);
|
||||
|
||||
// dst = (src + 0.5f) rounded down towards negative infinity
|
||||
// Adding 0.5f to some floats exceeds the precision limits for a float and rounding takes place.
|
||||
// RDN is required for fadd_s, RNE gives incorrect results:
|
||||
// --------------------------------------------------------------------
|
||||
// fadd.s rne (src + 0.5f): src = 8388609.000000 ftmp = 8388610.000000
|
||||
// fcvt.w.s rdn: ftmp = 8388610.000000 dst = 8388610
|
||||
// --------------------------------------------------------------------
|
||||
// fadd.s rdn (src + 0.5f): src = 8388609.000000 ftmp = 8388609.000000
|
||||
// fcvt.w.s rdn: ftmp = 8388609.000000 dst = 8388609
|
||||
// --------------------------------------------------------------------
|
||||
fadd_s(ftmp, src, ftmp, RoundingMode::rdn);
|
||||
fcvt_w_s(dst, ftmp, RoundingMode::rdn);
|
||||
|
||||
bind(done);
|
||||
}
|
||||
|
||||
// java.lang.Math.round(double a)
|
||||
// Returns the closest long to the argument, with ties rounding to positive infinity.
|
||||
void MacroAssembler::java_round_double(Register dst, FloatRegister src, FloatRegister ftmp) {
|
||||
// this instructions calling sequence provides performance improvement on all tested devices;
|
||||
// don't change it without re-verification
|
||||
Label done;
|
||||
mv(t0, julong_cast(0.5));
|
||||
fmv_d_x(ftmp, t0);
|
||||
|
||||
// dst = 0 if NaN
|
||||
feq_d(t0, src, src); // replacing fclass with feq as performance optimization
|
||||
mv(dst, zr);
|
||||
beqz(t0, done);
|
||||
|
||||
// dst = (src + 0.5) rounded down towards negative infinity
|
||||
fadd_d(ftmp, src, ftmp, RoundingMode::rdn); // RDN is required here otherwise some inputs produce incorrect results
|
||||
fcvt_l_d(dst, ftmp, RoundingMode::rdn);
|
||||
|
||||
bind(done);
|
||||
}
|
||||
|
||||
#define FCVT_SAFE(FLOATCVT, FLOATSIG) \
|
||||
void MacroAssembler::FLOATCVT##_safe(Register dst, FloatRegister src, Register tmp) { \
|
||||
Label done; \
|
||||
@@ -4488,41 +4678,54 @@ void MacroAssembler::shadd(Register Rd, Register Rs1, Register Rs2, Register tmp
|
||||
}
|
||||
|
||||
void MacroAssembler::zero_extend(Register dst, Register src, int bits) {
|
||||
if (UseZba && bits == 32) {
|
||||
zext_w(dst, src);
|
||||
return;
|
||||
}
|
||||
|
||||
if (UseZbb && bits == 16) {
|
||||
zext_h(dst, src);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bits == 8) {
|
||||
zext_b(dst, src);
|
||||
} else {
|
||||
slli(dst, src, XLEN - bits);
|
||||
srli(dst, dst, XLEN - bits);
|
||||
switch (bits) {
|
||||
case 32:
|
||||
if (UseZba) {
|
||||
zext_w(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (UseZbb) {
|
||||
zext_h(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (UseZbb) {
|
||||
zext_b(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
slli(dst, src, XLEN - bits);
|
||||
srli(dst, dst, XLEN - bits);
|
||||
}
|
||||
|
||||
void MacroAssembler::sign_extend(Register dst, Register src, int bits) {
|
||||
if (UseZbb) {
|
||||
if (bits == 8) {
|
||||
sext_b(dst, src);
|
||||
switch (bits) {
|
||||
case 32:
|
||||
sext_w(dst, src);
|
||||
return;
|
||||
} else if (bits == 16) {
|
||||
sext_h(dst, src);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (bits == 32) {
|
||||
sext_w(dst, src);
|
||||
} else {
|
||||
slli(dst, src, XLEN - bits);
|
||||
srai(dst, dst, XLEN - bits);
|
||||
case 16:
|
||||
if (UseZbb) {
|
||||
sext_h(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (UseZbb) {
|
||||
sext_b(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
slli(dst, src, XLEN - bits);
|
||||
srai(dst, dst, XLEN - bits);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_x2i(Register dst, Register src1, Register src2,
|
||||
@@ -4701,9 +4904,9 @@ void MacroAssembler::object_move(OopMap* map,
|
||||
|
||||
// A float arg may have to do float reg int reg conversion
|
||||
void MacroAssembler::float_move(VMRegPair src, VMRegPair dst, Register tmp) {
|
||||
assert(src.first()->is_stack() && dst.first()->is_stack() ||
|
||||
src.first()->is_reg() && dst.first()->is_reg() ||
|
||||
src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error");
|
||||
assert((src.first()->is_stack() && dst.first()->is_stack()) ||
|
||||
(src.first()->is_reg() && dst.first()->is_reg()) ||
|
||||
(src.first()->is_stack() && dst.first()->is_reg()), "Unexpected error");
|
||||
if (src.first()->is_stack()) {
|
||||
if (dst.first()->is_stack()) {
|
||||
lwu(tmp, Address(fp, reg2offset_in(src.first())));
|
||||
@@ -4745,9 +4948,9 @@ void MacroAssembler::long_move(VMRegPair src, VMRegPair dst, Register tmp) {
|
||||
|
||||
// A double move
|
||||
void MacroAssembler::double_move(VMRegPair src, VMRegPair dst, Register tmp) {
|
||||
assert(src.first()->is_stack() && dst.first()->is_stack() ||
|
||||
src.first()->is_reg() && dst.first()->is_reg() ||
|
||||
src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error");
|
||||
assert((src.first()->is_stack() && dst.first()->is_stack()) ||
|
||||
(src.first()->is_reg() && dst.first()->is_reg()) ||
|
||||
(src.first()->is_stack() && dst.first()->is_reg()), "Unexpected error");
|
||||
if (src.first()->is_stack()) {
|
||||
if (dst.first()->is_stack()) {
|
||||
ld(tmp, Address(fp, reg2offset_in(src.first())));
|
||||
|
||||
@@ -473,7 +473,11 @@ class MacroAssembler: public Assembler {
|
||||
}
|
||||
|
||||
inline void notr(Register Rd, Register Rs) {
|
||||
xori(Rd, Rs, -1);
|
||||
if (do_compress_zcb(Rd, Rs) && (Rd == Rs)) {
|
||||
c_not(Rd);
|
||||
} else {
|
||||
xori(Rd, Rs, -1);
|
||||
}
|
||||
}
|
||||
|
||||
inline void neg(Register Rd, Register Rs) {
|
||||
@@ -489,7 +493,11 @@ class MacroAssembler: public Assembler {
|
||||
}
|
||||
|
||||
inline void zext_b(Register Rd, Register Rs) {
|
||||
andi(Rd, Rs, 0xFF);
|
||||
if (do_compress_zcb(Rd, Rs) && (Rd == Rs)) {
|
||||
c_zext_b(Rd);
|
||||
} else {
|
||||
andi(Rd, Rs, 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
inline void seqz(Register Rd, Register Rs) {
|
||||
@@ -511,7 +519,12 @@ class MacroAssembler: public Assembler {
|
||||
// Bit-manipulation extension pseudo instructions
|
||||
// zero extend word
|
||||
inline void zext_w(Register Rd, Register Rs) {
|
||||
add_uw(Rd, Rs, zr);
|
||||
assert(UseZba, "must be");
|
||||
if (do_compress_zcb(Rd, Rs) && (Rd == Rs)) {
|
||||
c_zext_w(Rd);
|
||||
} else {
|
||||
add_uw(Rd, Rs, zr);
|
||||
}
|
||||
}
|
||||
|
||||
// Floating-point data-processing pseudo instructions
|
||||
@@ -1063,6 +1076,19 @@ public:
|
||||
void atomic_xchgwu(Register prev, Register newv, Register addr);
|
||||
void atomic_xchgalwu(Register prev, Register newv, Register addr);
|
||||
|
||||
void atomic_cas(Register prev, Register newv, Register addr);
|
||||
void atomic_casw(Register prev, Register newv, Register addr);
|
||||
void atomic_casl(Register prev, Register newv, Register addr);
|
||||
void atomic_caslw(Register prev, Register newv, Register addr);
|
||||
void atomic_casal(Register prev, Register newv, Register addr);
|
||||
void atomic_casalw(Register prev, Register newv, Register addr);
|
||||
void atomic_caswu(Register prev, Register newv, Register addr);
|
||||
void atomic_caslwu(Register prev, Register newv, Register addr);
|
||||
void atomic_casalwu(Register prev, Register newv, Register addr);
|
||||
|
||||
void atomic_cas(Register prev, Register newv, Register addr, enum operand_size size,
|
||||
Assembler::Aqrl acquire = Assembler::relaxed, Assembler::Aqrl release = Assembler::relaxed);
|
||||
|
||||
// Emit a far call/jump. Only invalidates the tmp register which
|
||||
// is used to keep the entry address for jalr.
|
||||
// The address must be inside the code cache.
|
||||
@@ -1252,6 +1278,9 @@ public:
|
||||
void fcvt_w_d_safe(Register dst, FloatRegister src, Register tmp = t0);
|
||||
void fcvt_l_d_safe(Register dst, FloatRegister src, Register tmp = t0);
|
||||
|
||||
void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
|
||||
void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
|
||||
|
||||
// vector load/store unit-stride instructions
|
||||
void vlex_v(VectorRegister vd, Register base, Assembler::SEW sew, VectorMask vm = unmasked) {
|
||||
switch (sew) {
|
||||
@@ -1345,6 +1374,16 @@ public:
|
||||
vmfle_vv(vd, vs1, vs2, vm);
|
||||
}
|
||||
|
||||
inline void vmsltu_vi(VectorRegister Vd, VectorRegister Vs2, uint32_t imm, VectorMask vm = unmasked) {
|
||||
guarantee(imm >= 1 && imm <= 16, "imm is invalid");
|
||||
vmsleu_vi(Vd, Vs2, imm-1, vm);
|
||||
}
|
||||
|
||||
inline void vmsgeu_vi(VectorRegister Vd, VectorRegister Vs2, uint32_t imm, VectorMask vm = unmasked) {
|
||||
guarantee(imm >= 1 && imm <= 16, "imm is invalid");
|
||||
vmsgtu_vi(Vd, Vs2, imm-1, vm);
|
||||
}
|
||||
|
||||
// Copy mask register
|
||||
inline void vmmv_m(VectorRegister vd, VectorRegister vs) {
|
||||
vmand_mm(vd, vs, vs);
|
||||
@@ -1360,6 +1399,10 @@ public:
|
||||
vmxnor_mm(vd, vd, vd);
|
||||
}
|
||||
|
||||
inline void vnot_v(VectorRegister Vd, VectorRegister Vs, VectorMask vm = unmasked) {
|
||||
vxor_vi(Vd, Vs, -1, vm);
|
||||
}
|
||||
|
||||
static const int zero_words_block_size;
|
||||
|
||||
void cast_primitive_type(BasicType type, Register Rt) {
|
||||
|
||||
@@ -192,4 +192,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Is SIMD sort supported for this CPU?
|
||||
static bool supports_simd_sort(BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // CPU_RISCV_MATCHER_RISCV_HPP
|
||||
|
||||
@@ -451,16 +451,27 @@ void NativePostCallNop::make_deopt() {
|
||||
NativeDeoptInstruction::insert(addr_at(0));
|
||||
}
|
||||
|
||||
int NativePostCallNop::displacement() const {
|
||||
bool NativePostCallNop::decode(int32_t& oopmap_slot, int32_t& cb_offset) const {
|
||||
// Discard the high 32 bits
|
||||
return (int)(intptr_t)MacroAssembler::get_target_of_li32(addr_at(4));
|
||||
int32_t data = (int32_t)(intptr_t)MacroAssembler::get_target_of_li32(addr_at(4));
|
||||
if (data == 0) {
|
||||
return false; // no information encoded
|
||||
}
|
||||
cb_offset = (data & 0xffffff);
|
||||
oopmap_slot = (data >> 24) & 0xff;
|
||||
return true; // decoding succeeded
|
||||
}
|
||||
|
||||
void NativePostCallNop::patch(jint diff) {
|
||||
assert(diff != 0, "must be");
|
||||
bool NativePostCallNop::patch(int32_t oopmap_slot, int32_t cb_offset) {
|
||||
if (((oopmap_slot & 0xff) != oopmap_slot) || ((cb_offset & 0xffffff) != cb_offset)) {
|
||||
return false; // cannot encode
|
||||
}
|
||||
int32_t data = (oopmap_slot << 24) | cb_offset;
|
||||
assert(data != 0, "must be");
|
||||
assert(is_lui_to_zr_at(addr_at(4)) && is_addiw_to_zr_at(addr_at(8)), "must be");
|
||||
|
||||
MacroAssembler::patch_imm_in_li32(addr_at(4), diff);
|
||||
MacroAssembler::patch_imm_in_li32(addr_at(4), data);
|
||||
return true; // successfully encoded
|
||||
}
|
||||
|
||||
void NativeDeoptInstruction::verify() {
|
||||
|
||||
@@ -591,8 +591,8 @@ public:
|
||||
// an addiw as well.
|
||||
return is_nop() && is_lui_to_zr_at(addr_at(4));
|
||||
}
|
||||
int displacement() const;
|
||||
void patch(jint diff);
|
||||
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const;
|
||||
bool patch(int32_t oopmap_slot, int32_t cb_offset);
|
||||
void make_deopt();
|
||||
};
|
||||
|
||||
|
||||
@@ -1001,6 +1001,7 @@ definitions %{
|
||||
int_def LOAD_COST ( 300, 3 * DEFAULT_COST); // load, fpload
|
||||
int_def STORE_COST ( 100, 1 * DEFAULT_COST); // store, fpstore
|
||||
int_def XFER_COST ( 300, 3 * DEFAULT_COST); // mfc, mtc, fcvt, fmove, fcmp
|
||||
int_def FMVX_COST ( 100, 1 * DEFAULT_COST); // shuffles with no conversion
|
||||
int_def BRANCH_COST ( 200, 2 * DEFAULT_COST); // branch, jmp, call
|
||||
int_def IMUL_COST ( 1000, 10 * DEFAULT_COST); // imul
|
||||
int_def IDIVSI_COST ( 3400, 34 * DEFAULT_COST); // idivsi
|
||||
@@ -8417,6 +8418,34 @@ instruct convN2I(iRegINoSp dst, iRegN src)
|
||||
ins_pipe(ialu_reg);
|
||||
%}
|
||||
|
||||
instruct round_double_reg(iRegLNoSp dst, fRegD src, fRegD ftmp) %{
|
||||
match(Set dst (RoundD src));
|
||||
|
||||
ins_cost(XFER_COST + BRANCH_COST);
|
||||
effect(TEMP ftmp);
|
||||
format %{ "java_round_double $dst, $src\t#@round_double_reg" %}
|
||||
|
||||
ins_encode %{
|
||||
__ java_round_double($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg));
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct round_float_reg(iRegINoSp dst, fRegF src, fRegF ftmp) %{
|
||||
match(Set dst (RoundF src));
|
||||
|
||||
ins_cost(XFER_COST + BRANCH_COST);
|
||||
effect(TEMP ftmp);
|
||||
format %{ "java_round_float $dst, $src\t#@round_float_reg" %}
|
||||
|
||||
ins_encode %{
|
||||
__ java_round_float($dst$$Register, as_FloatRegister($src$$reg), as_FloatRegister($ftmp$$reg));
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// Convert oop pointer into compressed form
|
||||
instruct encodeHeapOop(iRegNNoSp dst, iRegP src) %{
|
||||
match(Set dst (EncodeP src));
|
||||
@@ -8646,7 +8675,7 @@ instruct MoveF2I_reg_reg(iRegINoSp dst, fRegF src) %{
|
||||
|
||||
effect(DEF dst, USE src);
|
||||
|
||||
ins_cost(XFER_COST);
|
||||
ins_cost(FMVX_COST);
|
||||
|
||||
format %{ "fmv.x.w $dst, $src\t#@MoveF2I_reg_reg" %}
|
||||
|
||||
@@ -8664,7 +8693,7 @@ instruct MoveI2F_reg_reg(fRegF dst, iRegI src) %{
|
||||
|
||||
effect(DEF dst, USE src);
|
||||
|
||||
ins_cost(XFER_COST);
|
||||
ins_cost(FMVX_COST);
|
||||
|
||||
format %{ "fmv.w.x $dst, $src\t#@MoveI2F_reg_reg" %}
|
||||
|
||||
@@ -8682,7 +8711,7 @@ instruct MoveD2L_reg_reg(iRegLNoSp dst, fRegD src) %{
|
||||
|
||||
effect(DEF dst, USE src);
|
||||
|
||||
ins_cost(XFER_COST);
|
||||
ins_cost(FMVX_COST);
|
||||
|
||||
format %{ "fmv.x.d $dst, $src\t#@MoveD2L_reg_reg" %}
|
||||
|
||||
@@ -8700,7 +8729,7 @@ instruct MoveL2D_reg_reg(fRegD dst, iRegL src) %{
|
||||
|
||||
effect(DEF dst, USE src);
|
||||
|
||||
ins_cost(XFER_COST);
|
||||
ins_cost(FMVX_COST);
|
||||
|
||||
format %{ "fmv.d.x $dst, $src\t#@MoveL2D_reg_reg" %}
|
||||
|
||||
@@ -10371,6 +10400,26 @@ instruct array_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result,
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
||||
// fast ArraysSupport.vectorizedHashCode
|
||||
instruct arrays_hashcode(iRegP_R11 ary, iRegI_R12 cnt, iRegI_R10 result, immI basic_type,
|
||||
iRegLNoSp tmp1, iRegLNoSp tmp2,
|
||||
iRegLNoSp tmp3, iRegLNoSp tmp4,
|
||||
iRegLNoSp tmp5, iRegLNoSp tmp6, rFlagsReg cr)
|
||||
%{
|
||||
match(Set result (VectorizedHashCode (Binary ary cnt) (Binary result basic_type)));
|
||||
effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6,
|
||||
USE_KILL ary, USE_KILL cnt, USE basic_type, KILL cr);
|
||||
|
||||
format %{ "Array HashCode array[] $ary,$cnt,$result,$basic_type -> $result // KILL all" %}
|
||||
ins_encode %{
|
||||
__ arrays_hashcode($ary$$Register, $cnt$$Register, $result$$Register,
|
||||
$tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
|
||||
$tmp4$$Register, $tmp5$$Register, $tmp6$$Register,
|
||||
(BasicType)$basic_type$$constant);
|
||||
%}
|
||||
ins_pipe(pipe_class_memory);
|
||||
%}
|
||||
|
||||
// ============================================================================
|
||||
// Safepoint Instructions
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
|
||||
uint int_args = 0;
|
||||
uint fp_args = 0;
|
||||
uint stk_args = 0; // inc by 2 each time
|
||||
uint stk_args = 0;
|
||||
|
||||
for (int i = 0; i < total_args_passed; i++) {
|
||||
switch (sig_bt[i]) {
|
||||
@@ -278,8 +278,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (int_args < Argument::n_int_register_parameters_j) {
|
||||
regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set1(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
stk_args += 1;
|
||||
}
|
||||
break;
|
||||
case T_VOID:
|
||||
@@ -295,6 +296,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (int_args < Argument::n_int_register_parameters_j) {
|
||||
regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set2(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
}
|
||||
@@ -303,8 +305,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (fp_args < Argument::n_float_register_parameters_j) {
|
||||
regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set1(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
stk_args += 1;
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
@@ -312,6 +315,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (fp_args < Argument::n_float_register_parameters_j) {
|
||||
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set2(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
}
|
||||
@@ -321,7 +325,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
}
|
||||
|
||||
return align_up(stk_args, 2);
|
||||
return stk_args;
|
||||
}
|
||||
|
||||
// Patch the callers callsite with entry to compiled code if it exists.
|
||||
@@ -1675,7 +1679,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
__ sd(swap_reg, Address(lock_reg, mark_word_offset));
|
||||
|
||||
// src -> dest if dest == x10 else x10 <- dest
|
||||
__ cmpxchg_obj_header(x10, lock_reg, obj_reg, t0, count, /*fallthrough*/nullptr);
|
||||
__ cmpxchg_obj_header(x10, lock_reg, obj_reg, lock_tmp, count, /*fallthrough*/nullptr);
|
||||
|
||||
// Test if the oopMark is an obvious stack pointer, i.e.,
|
||||
// 1) (mark & 3) == 0, and
|
||||
@@ -1815,7 +1819,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
|
||||
// Atomic swap old header if oop still contains the stack lock
|
||||
Label count;
|
||||
__ cmpxchg_obj_header(x10, old_hdr, obj_reg, t0, count, &slow_path_unlock);
|
||||
__ cmpxchg_obj_header(x10, old_hdr, obj_reg, lock_tmp, count, &slow_path_unlock);
|
||||
__ bind(count);
|
||||
__ decrement(Address(xthread, JavaThread::held_monitor_count_offset()));
|
||||
} else {
|
||||
|
||||
@@ -3659,8 +3659,394 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return entry;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // COMPILER2
|
||||
|
||||
#undef __
|
||||
#define __ this->
|
||||
class Sha2Generator : public MacroAssembler {
|
||||
StubCodeGenerator* _cgen;
|
||||
public:
|
||||
Sha2Generator(MacroAssembler* masm, StubCodeGenerator* cgen) : MacroAssembler(masm->code()), _cgen(cgen) {}
|
||||
address generate_sha256_implCompress(bool multi_block) {
|
||||
return generate_sha2_implCompress(Assembler::e32, multi_block);
|
||||
}
|
||||
address generate_sha512_implCompress(bool multi_block) {
|
||||
return generate_sha2_implCompress(Assembler::e64, multi_block);
|
||||
}
|
||||
private:
|
||||
|
||||
void vleXX_v(Assembler::SEW vset_sew, VectorRegister vr, Register sr) {
|
||||
if (vset_sew == Assembler::e32) __ vle32_v(vr, sr);
|
||||
else __ vle64_v(vr, sr);
|
||||
}
|
||||
|
||||
void vseXX_v(Assembler::SEW vset_sew, VectorRegister vr, Register sr) {
|
||||
if (vset_sew == Assembler::e32) __ vse32_v(vr, sr);
|
||||
else __ vse64_v(vr, sr);
|
||||
}
|
||||
|
||||
// Overview of the logic in each "quad round".
|
||||
//
|
||||
// The code below repeats 16/20 times the logic implementing four rounds
|
||||
// of the SHA-256/512 core loop as documented by NIST. 16/20 "quad rounds"
|
||||
// to implementing the 64/80 single rounds.
|
||||
//
|
||||
// // Load four word (u32/64) constants (K[t+3], K[t+2], K[t+1], K[t+0])
|
||||
// // Output:
|
||||
// // vTmp1 = {K[t+3], K[t+2], K[t+1], K[t+0]}
|
||||
// vl1reXX.v vTmp1, ofs
|
||||
//
|
||||
// // Increment word constant address by stride (16/32 bytes, 4*4B/8B, 128b/256b)
|
||||
// addi ofs, ofs, 16/32
|
||||
//
|
||||
// // Add constants to message schedule words:
|
||||
// // Input
|
||||
// // vTmp1 = {K[t+3], K[t+2], K[t+1], K[t+0]}
|
||||
// // vW0 = {W[t+3], W[t+2], W[t+1], W[t+0]}; // Vt0 = W[3:0];
|
||||
// // Output
|
||||
// // vTmp0 = {W[t+3]+K[t+3], W[t+2]+K[t+2], W[t+1]+K[t+1], W[t+0]+K[t+0]}
|
||||
// vadd.vv vTmp0, vTmp1, vW0
|
||||
//
|
||||
// // 2 rounds of working variables updates.
|
||||
// // vState1[t+4] <- vState1[t], vState0[t], vTmp0[t]
|
||||
// // Input:
|
||||
// // vState1 = {c[t],d[t],g[t],h[t]} " = vState1[t] "
|
||||
// // vState0 = {a[t],b[t],e[t],f[t]}
|
||||
// // vTmp0 = {W[t+3]+K[t+3], W[t+2]+K[t+2], W[t+1]+K[t+1], W[t+0]+K[t+0]}
|
||||
// // Output:
|
||||
// // vState1 = {f[t+2],e[t+2],b[t+2],a[t+2]} " = vState0[t+2] "
|
||||
// // = {h[t+4],g[t+4],d[t+4],c[t+4]} " = vState1[t+4] "
|
||||
// vsha2cl.vv vState1, vState0, vTmp0
|
||||
//
|
||||
// // 2 rounds of working variables updates.
|
||||
// // vState0[t+4] <- vState0[t], vState0[t+2], vTmp0[t]
|
||||
// // Input
|
||||
// // vState0 = {a[t],b[t],e[t],f[t]} " = vState0[t] "
|
||||
// // = {h[t+2],g[t+2],d[t+2],c[t+2]} " = vState1[t+2] "
|
||||
// // vState1 = {f[t+2],e[t+2],b[t+2],a[t+2]} " = vState0[t+2] "
|
||||
// // vTmp0 = {W[t+3]+K[t+3], W[t+2]+K[t+2], W[t+1]+K[t+1], W[t+0]+K[t+0]}
|
||||
// // Output:
|
||||
// // vState0 = {f[t+4],e[t+4],b[t+4],a[t+4]} " = vState0[t+4] "
|
||||
// vsha2ch.vv vState0, vState1, vTmp0
|
||||
//
|
||||
// // Combine 2QW into 1QW
|
||||
// //
|
||||
// // To generate the next 4 words, "new_vW0"/"vTmp0" from vW0-vW3, vsha2ms needs
|
||||
// // vW0[0..3], vW1[0], vW2[1..3], vW3[0, 2..3]
|
||||
// // and it can only take 3 vectors as inputs. Hence we need to combine
|
||||
// // vW1[0] and vW2[1..3] in a single vector.
|
||||
// //
|
||||
// // vmerge Vt4, Vt1, Vt2, V0
|
||||
// // Input
|
||||
// // V0 = mask // first word from vW2, 1..3 words from vW1
|
||||
// // vW2 = {Wt-8, Wt-7, Wt-6, Wt-5}
|
||||
// // vW1 = {Wt-12, Wt-11, Wt-10, Wt-9}
|
||||
// // Output
|
||||
// // Vt4 = {Wt-12, Wt-7, Wt-6, Wt-5}
|
||||
// vmerge.vvm vTmp0, vW2, vW1, v0
|
||||
//
|
||||
// // Generate next Four Message Schedule Words (hence allowing for 4 more rounds)
|
||||
// // Input
|
||||
// // vW0 = {W[t+ 3], W[t+ 2], W[t+ 1], W[t+ 0]} W[ 3: 0]
|
||||
// // vW3 = {W[t+15], W[t+14], W[t+13], W[t+12]} W[15:12]
|
||||
// // vTmp0 = {W[t+11], W[t+10], W[t+ 9], W[t+ 4]} W[11: 9,4]
|
||||
// // Output (next four message schedule words)
|
||||
// // vW0 = {W[t+19], W[t+18], W[t+17], W[t+16]} W[19:16]
|
||||
// vsha2ms.vv vW0, vTmp0, vW3
|
||||
//
|
||||
// BEFORE
|
||||
// vW0 - vW3 hold the message schedule words (initially the block words)
|
||||
// vW0 = W[ 3: 0] "oldest"
|
||||
// vW1 = W[ 7: 4]
|
||||
// vW2 = W[11: 8]
|
||||
// vW3 = W[15:12] "newest"
|
||||
//
|
||||
// vt6 - vt7 hold the working state variables
|
||||
// vState0 = {a[t],b[t],e[t],f[t]} // initially {H5,H4,H1,H0}
|
||||
// vState1 = {c[t],d[t],g[t],h[t]} // initially {H7,H6,H3,H2}
|
||||
//
|
||||
// AFTER
|
||||
// vW0 - vW3 hold the message schedule words (initially the block words)
|
||||
// vW1 = W[ 7: 4] "oldest"
|
||||
// vW2 = W[11: 8]
|
||||
// vW3 = W[15:12]
|
||||
// vW0 = W[19:16] "newest"
|
||||
//
|
||||
// vState0 and vState1 hold the working state variables
|
||||
// vState0 = {a[t+4],b[t+4],e[t+4],f[t+4]}
|
||||
// vState1 = {c[t+4],d[t+4],g[t+4],h[t+4]}
|
||||
//
|
||||
// The group of vectors vW0,vW1,vW2,vW3 is "rotated" by one in each quad-round,
|
||||
// hence the uses of those vectors rotate in each round, and we get back to the
|
||||
// initial configuration every 4 quad-rounds. We could avoid those changes at
|
||||
// the cost of moving those vectors at the end of each quad-rounds.
|
||||
void sha2_quad_round(Assembler::SEW vset_sew, VectorRegister rot1, VectorRegister rot2, VectorRegister rot3, VectorRegister rot4,
|
||||
Register scalarconst, VectorRegister vtemp, VectorRegister vtemp2, VectorRegister v_abef, VectorRegister v_cdgh,
|
||||
bool gen_words = true, bool step_const = true) {
|
||||
__ vleXX_v(vset_sew, vtemp, scalarconst);
|
||||
if (step_const) {
|
||||
__ addi(scalarconst, scalarconst, vset_sew == Assembler::e32 ? 16 : 32);
|
||||
}
|
||||
__ vadd_vv(vtemp2, vtemp, rot1);
|
||||
__ vsha2cl_vv(v_cdgh, v_abef, vtemp2);
|
||||
__ vsha2ch_vv(v_abef, v_cdgh, vtemp2);
|
||||
if (gen_words) {
|
||||
__ vmerge_vvm(vtemp2, rot3, rot2);
|
||||
__ vsha2ms_vv(rot1, vtemp2, rot4);
|
||||
}
|
||||
}
|
||||
|
||||
const char* stub_name(Assembler::SEW vset_sew, bool multi_block) {
|
||||
if (vset_sew == Assembler::e32 && !multi_block) return "sha256_implCompress";
|
||||
if (vset_sew == Assembler::e32 && multi_block) return "sha256_implCompressMB";
|
||||
if (vset_sew == Assembler::e64 && !multi_block) return "sha512_implCompress";
|
||||
if (vset_sew == Assembler::e64 && multi_block) return "sha512_implCompressMB";
|
||||
ShouldNotReachHere();
|
||||
return "bad name lookup";
|
||||
}
|
||||
|
||||
// Arguments:
|
||||
//
|
||||
// Inputs:
|
||||
// c_rarg0 - byte[] source+offset
|
||||
// c_rarg1 - int[] SHA.state
|
||||
// c_rarg2 - int offset
|
||||
// c_rarg3 - int limit
|
||||
//
|
||||
address generate_sha2_implCompress(Assembler::SEW vset_sew, bool multi_block) {
|
||||
alignas(64) static const uint32_t round_consts_256[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
||||
};
|
||||
alignas(64) static const uint64_t round_consts_512[80] = {
|
||||
0x428a2f98d728ae22l, 0x7137449123ef65cdl, 0xb5c0fbcfec4d3b2fl,
|
||||
0xe9b5dba58189dbbcl, 0x3956c25bf348b538l, 0x59f111f1b605d019l,
|
||||
0x923f82a4af194f9bl, 0xab1c5ed5da6d8118l, 0xd807aa98a3030242l,
|
||||
0x12835b0145706fbel, 0x243185be4ee4b28cl, 0x550c7dc3d5ffb4e2l,
|
||||
0x72be5d74f27b896fl, 0x80deb1fe3b1696b1l, 0x9bdc06a725c71235l,
|
||||
0xc19bf174cf692694l, 0xe49b69c19ef14ad2l, 0xefbe4786384f25e3l,
|
||||
0x0fc19dc68b8cd5b5l, 0x240ca1cc77ac9c65l, 0x2de92c6f592b0275l,
|
||||
0x4a7484aa6ea6e483l, 0x5cb0a9dcbd41fbd4l, 0x76f988da831153b5l,
|
||||
0x983e5152ee66dfabl, 0xa831c66d2db43210l, 0xb00327c898fb213fl,
|
||||
0xbf597fc7beef0ee4l, 0xc6e00bf33da88fc2l, 0xd5a79147930aa725l,
|
||||
0x06ca6351e003826fl, 0x142929670a0e6e70l, 0x27b70a8546d22ffcl,
|
||||
0x2e1b21385c26c926l, 0x4d2c6dfc5ac42aedl, 0x53380d139d95b3dfl,
|
||||
0x650a73548baf63del, 0x766a0abb3c77b2a8l, 0x81c2c92e47edaee6l,
|
||||
0x92722c851482353bl, 0xa2bfe8a14cf10364l, 0xa81a664bbc423001l,
|
||||
0xc24b8b70d0f89791l, 0xc76c51a30654be30l, 0xd192e819d6ef5218l,
|
||||
0xd69906245565a910l, 0xf40e35855771202al, 0x106aa07032bbd1b8l,
|
||||
0x19a4c116b8d2d0c8l, 0x1e376c085141ab53l, 0x2748774cdf8eeb99l,
|
||||
0x34b0bcb5e19b48a8l, 0x391c0cb3c5c95a63l, 0x4ed8aa4ae3418acbl,
|
||||
0x5b9cca4f7763e373l, 0x682e6ff3d6b2b8a3l, 0x748f82ee5defb2fcl,
|
||||
0x78a5636f43172f60l, 0x84c87814a1f0ab72l, 0x8cc702081a6439ecl,
|
||||
0x90befffa23631e28l, 0xa4506cebde82bde9l, 0xbef9a3f7b2c67915l,
|
||||
0xc67178f2e372532bl, 0xca273eceea26619cl, 0xd186b8c721c0c207l,
|
||||
0xeada7dd6cde0eb1el, 0xf57d4f7fee6ed178l, 0x06f067aa72176fbal,
|
||||
0x0a637dc5a2c898a6l, 0x113f9804bef90dael, 0x1b710b35131c471bl,
|
||||
0x28db77f523047d84l, 0x32caab7b40c72493l, 0x3c9ebe0a15c9bebcl,
|
||||
0x431d67c49c100d4cl, 0x4cc5d4becb3e42b6l, 0x597f299cfc657e2al,
|
||||
0x5fcb6fab3ad6faecl, 0x6c44198c4a475817l
|
||||
};
|
||||
const int const_add = vset_sew == Assembler::e32 ? 16 : 32;
|
||||
|
||||
__ align(CodeEntryAlignment);
|
||||
StubCodeMark mark(_cgen, "StubRoutines", stub_name(vset_sew, multi_block));
|
||||
address start = __ pc();
|
||||
|
||||
Register buf = c_rarg0;
|
||||
Register state = c_rarg1;
|
||||
Register ofs = c_rarg2;
|
||||
Register limit = c_rarg3;
|
||||
Register consts = t2; // caller saved
|
||||
Register state_c = x28; // caller saved
|
||||
VectorRegister vindex = v2;
|
||||
VectorRegister vW0 = v4;
|
||||
VectorRegister vW1 = v6;
|
||||
VectorRegister vW2 = v8;
|
||||
VectorRegister vW3 = v10;
|
||||
VectorRegister vState0 = v12;
|
||||
VectorRegister vState1 = v14;
|
||||
VectorRegister vHash0 = v16;
|
||||
VectorRegister vHash1 = v18;
|
||||
VectorRegister vTmp0 = v20;
|
||||
VectorRegister vTmp1 = v22;
|
||||
|
||||
Label multi_block_loop;
|
||||
|
||||
__ enter();
|
||||
|
||||
address constant_table = vset_sew == Assembler::e32 ? (address)round_consts_256 : (address)round_consts_512;
|
||||
la(consts, ExternalAddress(constant_table));
|
||||
|
||||
// Register use in this function:
|
||||
//
|
||||
// VECTORS
|
||||
// vW0 - vW3 (512/1024-bits / 4*128/256 bits / 4*4*32/65 bits), hold the message
|
||||
// schedule words (Wt). They start with the message block
|
||||
// content (W0 to W15), then further words in the message
|
||||
// schedule generated via vsha2ms from previous Wt.
|
||||
// Initially:
|
||||
// vW0 = W[ 3:0] = { W3, W2, W1, W0}
|
||||
// vW1 = W[ 7:4] = { W7, W6, W5, W4}
|
||||
// vW2 = W[ 11:8] = {W11, W10, W9, W8}
|
||||
// vW3 = W[15:12] = {W15, W14, W13, W12}
|
||||
//
|
||||
// vState0 - vState1 hold the working state variables (a, b, ..., h)
|
||||
// vState0 = {f[t],e[t],b[t],a[t]}
|
||||
// vState1 = {h[t],g[t],d[t],c[t]}
|
||||
// Initially:
|
||||
// vState0 = {H5i-1, H4i-1, H1i-1 , H0i-1}
|
||||
// vState1 = {H7i-i, H6i-1, H3i-1 , H2i-1}
|
||||
//
|
||||
// v0 = masks for vrgather/vmerge. Single value during the 16 rounds.
|
||||
//
|
||||
// vTmp0 = temporary, Wt+Kt
|
||||
// vTmp1 = temporary, Kt
|
||||
//
|
||||
// vHash0/vHash1 = hold the initial values of the hash, byte-swapped.
|
||||
//
|
||||
// During most of the function the vector state is configured so that each
|
||||
// vector is interpreted as containing four 32/64 bits (e32/e64) elements (128/256 bits).
|
||||
|
||||
// vsha2ch/vsha2cl uses EGW of 4*SEW.
|
||||
// SHA256 SEW = e32, EGW = 128-bits
|
||||
// SHA512 SEW = e64, EGW = 256-bits
|
||||
//
|
||||
// VLEN is required to be at least 128.
|
||||
// For the case of VLEN=128 and SHA512 we need LMUL=2 to work with 4*e64 (EGW = 256)
|
||||
//
|
||||
// m1: LMUL=1/2
|
||||
// ta: tail agnostic (don't care about those lanes)
|
||||
// ma: mask agnostic (don't care about those lanes)
|
||||
// x0 is not written, we known the number of vector elements.
|
||||
|
||||
if (vset_sew == Assembler::e64 && MaxVectorSize == 16) { // SHA512 and VLEN = 128
|
||||
__ vsetivli(x0, 4, vset_sew, Assembler::m2, Assembler::ma, Assembler::ta);
|
||||
} else {
|
||||
__ vsetivli(x0, 4, vset_sew, Assembler::m1, Assembler::ma, Assembler::ta);
|
||||
}
|
||||
|
||||
int64_t indexes = vset_sew == Assembler::e32 ? 0x00041014ul : 0x00082028ul;
|
||||
__ li(t0, indexes);
|
||||
__ vmv_v_x(vindex, t0);
|
||||
|
||||
// Step-over a,b, so we are pointing to c.
|
||||
// const_add is equal to 4x state variable, div by 2 is thus 2, a,b
|
||||
__ addi(state_c, state, const_add/2);
|
||||
|
||||
// Use index-load to get {f,e,b,a},{h,g,d,c}
|
||||
__ vluxei8_v(vState0, state, vindex);
|
||||
__ vluxei8_v(vState1, state_c, vindex);
|
||||
|
||||
__ bind(multi_block_loop);
|
||||
|
||||
// Capture the initial H values in vHash0 and vHash1 to allow for computing
|
||||
// the resulting H', since H' = H+{a',b',c',...,h'}.
|
||||
__ vmv_v_v(vHash0, vState0);
|
||||
__ vmv_v_v(vHash1, vState1);
|
||||
|
||||
// Load the 512/1024-bits of the message block in vW0-vW3 and perform
|
||||
// an endian swap on each 4/8 bytes element.
|
||||
//
|
||||
// If Zvkb is not implemented one can use vrgather
|
||||
// with an index sequence to byte-swap.
|
||||
// sequence = [3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12]
|
||||
// <https://oeis.org/A004444> gives us "N ^ 3" as a nice formula to generate
|
||||
// this sequence. 'vid' gives us the N.
|
||||
__ vleXX_v(vset_sew, vW0, buf);
|
||||
__ vrev8_v(vW0, vW0);
|
||||
__ addi(buf, buf, const_add);
|
||||
__ vleXX_v(vset_sew, vW1, buf);
|
||||
__ vrev8_v(vW1, vW1);
|
||||
__ addi(buf, buf, const_add);
|
||||
__ vleXX_v(vset_sew, vW2, buf);
|
||||
__ vrev8_v(vW2, vW2);
|
||||
__ addi(buf, buf, const_add);
|
||||
__ vleXX_v(vset_sew, vW3, buf);
|
||||
__ vrev8_v(vW3, vW3);
|
||||
__ addi(buf, buf, const_add);
|
||||
|
||||
// Set v0 up for the vmerge that replaces the first word (idx==0)
|
||||
__ vid_v(v0);
|
||||
__ vmseq_vi(v0, v0, 0x0); // v0.mask[i] = (i == 0 ? 1 : 0)
|
||||
|
||||
VectorRegister rotation_regs[] = {vW0, vW1, vW2, vW3};
|
||||
int rot_pos = 0;
|
||||
// Quad-round #0 (+0, vW0->vW1->vW2->vW3) ... #11 (+3, vW3->vW0->vW1->vW2)
|
||||
const int qr_end = vset_sew == Assembler::e32 ? 12 : 16;
|
||||
for (int i = 0; i < qr_end; i++) {
|
||||
sha2_quad_round(vset_sew,
|
||||
rotation_regs[(rot_pos + 0) & 0x3],
|
||||
rotation_regs[(rot_pos + 1) & 0x3],
|
||||
rotation_regs[(rot_pos + 2) & 0x3],
|
||||
rotation_regs[(rot_pos + 3) & 0x3],
|
||||
consts,
|
||||
vTmp1, vTmp0, vState0, vState1);
|
||||
++rot_pos;
|
||||
}
|
||||
// Quad-round #12 (+0, vW0->vW1->vW2->vW3) ... #15 (+3, vW3->vW0->vW1->vW2)
|
||||
// Note that we stop generating new message schedule words (Wt, vW0-13)
|
||||
// as we already generated all the words we end up consuming (i.e., W[63:60]).
|
||||
const int qr_c_end = qr_end + 4;
|
||||
for (int i = qr_end; i < qr_c_end; i++) {
|
||||
sha2_quad_round(vset_sew,
|
||||
rotation_regs[(rot_pos + 0) & 0x3],
|
||||
rotation_regs[(rot_pos + 1) & 0x3],
|
||||
rotation_regs[(rot_pos + 2) & 0x3],
|
||||
rotation_regs[(rot_pos + 3) & 0x3],
|
||||
consts,
|
||||
vTmp1, vTmp0, vState0, vState1, false, i < (qr_c_end-1));
|
||||
++rot_pos;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// Compute the updated hash value H'
|
||||
// H' = H + {h',g',...,b',a'}
|
||||
// = {h,g,...,b,a} + {h',g',...,b',a'}
|
||||
// = {h+h',g+g',...,b+b',a+a'}
|
||||
|
||||
// H' = H+{a',b',c',...,h'}
|
||||
__ vadd_vv(vState0, vHash0, vState0);
|
||||
__ vadd_vv(vState1, vHash1, vState1);
|
||||
|
||||
if (multi_block) {
|
||||
int total_adds = vset_sew == Assembler::e32 ? 240 : 608;
|
||||
__ addi(consts, consts, -total_adds);
|
||||
__ add(ofs, ofs, vset_sew == Assembler::e32 ? 64 : 128);
|
||||
__ ble(ofs, limit, multi_block_loop);
|
||||
__ mv(c_rarg0, ofs); // return ofs
|
||||
}
|
||||
|
||||
// Store H[0..8] = {a,b,c,d,e,f,g,h} from
|
||||
// vState0 = {f,e,b,a}
|
||||
// vState1 = {h,g,d,c}
|
||||
__ vsuxei8_v(vState0, state, vindex);
|
||||
__ vsuxei8_v(vState1, state_c, vindex);
|
||||
|
||||
__ leave();
|
||||
__ ret();
|
||||
|
||||
return start;
|
||||
}
|
||||
};
|
||||
#undef __
|
||||
#define __ masm->
|
||||
|
||||
// Continuation point for throwing of implicit exceptions that are
|
||||
// not handled in the current activation. Fabricates an exception
|
||||
// oop and initiates normal exception dispatching in this
|
||||
@@ -4155,14 +4541,18 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
// to minimize the number of memory operations:
|
||||
// read the 4 state 4-byte values in pairs, with a single ld,
|
||||
// and split them into 2 registers
|
||||
__ mv(t0, mask32);
|
||||
// and split them into 2 registers.
|
||||
//
|
||||
// And, as the core algorithm of md5 works on 32-bits words, so
|
||||
// in the following code, it does not care about the content of
|
||||
// higher 32-bits in state[x]. Based on this observation,
|
||||
// we can apply further optimization, which is to just ignore the
|
||||
// higher 32-bits in state0/state2, rather than set the higher
|
||||
// 32-bits of state0/state2 to zero explicitly with extra instructions.
|
||||
__ ld(state0, Address(state));
|
||||
__ srli(state1, state0, 32);
|
||||
__ andr(state0, state0, t0);
|
||||
__ ld(state2, Address(state, 8));
|
||||
__ srli(state3, state2, 32);
|
||||
__ andr(state2, state2, t0);
|
||||
|
||||
Label md5_loop;
|
||||
__ BIND(md5_loop);
|
||||
@@ -4858,6 +5248,18 @@ static const int64_t right_3_bits = right_n_bits(3);
|
||||
}
|
||||
#endif // COMPILER2
|
||||
|
||||
if (UseSHA256Intrinsics) {
|
||||
Sha2Generator sha2(_masm, this);
|
||||
StubRoutines::_sha256_implCompress = sha2.generate_sha256_implCompress(false);
|
||||
StubRoutines::_sha256_implCompressMB = sha2.generate_sha256_implCompress(true);
|
||||
}
|
||||
|
||||
if (UseSHA512Intrinsics) {
|
||||
Sha2Generator sha2(_masm, this);
|
||||
StubRoutines::_sha512_implCompress = sha2.generate_sha512_implCompress(false);
|
||||
StubRoutines::_sha512_implCompressMB = sha2.generate_sha512_implCompress(true);
|
||||
}
|
||||
|
||||
generate_compare_long_strings();
|
||||
|
||||
generate_string_indexof_stubs();
|
||||
|
||||
@@ -146,26 +146,11 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
|
||||
}
|
||||
|
||||
if (UseSHA) {
|
||||
warning("SHA instructions are not available on this CPU");
|
||||
FLAG_SET_DEFAULT(UseSHA, false);
|
||||
}
|
||||
|
||||
if (UseSHA1Intrinsics) {
|
||||
warning("Intrinsics for SHA-1 crypto hash functions not available on this CPU.");
|
||||
FLAG_SET_DEFAULT(UseSHA1Intrinsics, false);
|
||||
}
|
||||
|
||||
if (UseSHA256Intrinsics) {
|
||||
warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU.");
|
||||
FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
|
||||
}
|
||||
|
||||
if (UseSHA512Intrinsics) {
|
||||
warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU.");
|
||||
FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
|
||||
}
|
||||
|
||||
if (UseSHA3Intrinsics) {
|
||||
warning("Intrinsics for SHA3-224, SHA3-256, SHA3-384 and SHA3-512 crypto hash functions not available on this CPU.");
|
||||
FLAG_SET_DEFAULT(UseSHA3Intrinsics, false);
|
||||
@@ -272,6 +257,10 @@ void VM_Version::initialize() {
|
||||
// NOTE: Make sure codes dependent on UseRVV are put after c2_initialize(),
|
||||
// as there are extra checks inside it which could disable UseRVV
|
||||
// in some situations.
|
||||
if (UseZvkn && !UseRVV) {
|
||||
FLAG_SET_DEFAULT(UseZvkn, false);
|
||||
warning("Cannot enable Zvkn on cpu without RVV support.");
|
||||
}
|
||||
|
||||
if (UseRVV) {
|
||||
if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
|
||||
@@ -283,6 +272,31 @@ void VM_Version::initialize() {
|
||||
}
|
||||
FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
|
||||
}
|
||||
|
||||
if (!UseZvkn && UseSHA) {
|
||||
warning("SHA instructions are not available on this CPU");
|
||||
FLAG_SET_DEFAULT(UseSHA, false);
|
||||
} else if (UseZvkn && FLAG_IS_DEFAULT(UseSHA)) {
|
||||
FLAG_SET_DEFAULT(UseSHA, true);
|
||||
}
|
||||
|
||||
if (!UseSHA) {
|
||||
if (UseSHA256Intrinsics) {
|
||||
warning("Intrinsics for SHA-224 and SHA-256 crypto hash functions not available on this CPU, UseZvkn needed.");
|
||||
FLAG_SET_DEFAULT(UseSHA256Intrinsics, false);
|
||||
}
|
||||
if (UseSHA512Intrinsics) {
|
||||
warning("Intrinsics for SHA-384 and SHA-512 crypto hash functions not available on this CPU, UseZvkn needed.");
|
||||
FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
|
||||
}
|
||||
} else {
|
||||
if (FLAG_IS_DEFAULT(UseSHA256Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseSHA256Intrinsics, true);
|
||||
}
|
||||
if (FLAG_IS_DEFAULT(UseSHA512Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseSHA512Intrinsics, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef COMPILER2
|
||||
@@ -315,6 +329,10 @@ void VM_Version::c2_initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(UseVectorizedHashCodeIntrinsic)) {
|
||||
FLAG_SET_DEFAULT(UseVectorizedHashCodeIntrinsic, true);
|
||||
}
|
||||
|
||||
if (!UseZicbop) {
|
||||
if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) {
|
||||
warning("Zicbop is not available on this CPU");
|
||||
|
||||
@@ -110,6 +110,9 @@ class VM_Version : public Abstract_VM_Version {
|
||||
// Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space.
|
||||
// Zihintpause Pause instruction HINT
|
||||
//
|
||||
// Zc Code Size Reduction - Additional compressed instructions.
|
||||
// Zcb Simple code-size saving instructions
|
||||
//
|
||||
// Other features and settings
|
||||
// mvendorid Manufactory JEDEC id encoded, ISA vol 2 3.1.2..
|
||||
// marchid Id for microarch. Mvendorid plus marchid uniquely identify the microarch.
|
||||
@@ -117,6 +120,8 @@ class VM_Version : public Abstract_VM_Version {
|
||||
// unaligned_access Unaligned memory accesses (unknown, unspported, emulated, slow, firmware, fast)
|
||||
// satp mode SATP bits (number of virtual addr bits) mbare, sv39, sv48, sv57, sv64
|
||||
|
||||
public:
|
||||
|
||||
#define RV_NO_FLAG_BIT (BitsPerWord+1) // nth_bit will return 0 on values larger than BitsPerWord
|
||||
|
||||
// declaration name , extension name, bit pos ,in str, mapped flag)
|
||||
@@ -137,11 +142,13 @@ class VM_Version : public Abstract_VM_Version {
|
||||
decl(ext_Zbb , "Zbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \
|
||||
decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
|
||||
decl(ext_Zcb , "Zcb" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zic64b , "Zic64b" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZic64b)) \
|
||||
decl(ext_Ztso , "Ztso" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZtso)) \
|
||||
decl(ext_Zihintpause , "Zihintpause" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZihintpause)) \
|
||||
decl(ext_Zacas , "Zacas" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZacas)) \
|
||||
decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
@@ -208,6 +215,9 @@ class VM_Version : public Abstract_VM_Version {
|
||||
constexpr static bool supports_stack_watermark_barrier() { return true; }
|
||||
|
||||
static bool supports_on_spin_wait() { return UseZihintpause; }
|
||||
|
||||
// RISCV64 supports fast class initialization checks
|
||||
static bool supports_fast_class_init_checks() { return true; }
|
||||
};
|
||||
|
||||
#endif // CPU_RISCV_VM_VERSION_RISCV_HPP
|
||||
|
||||
@@ -95,9 +95,9 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
address stub = find_stub();
|
||||
guarantee(stub != nullptr, "stub not found");
|
||||
|
||||
if (TraceICs) {
|
||||
{
|
||||
ResourceMark rm;
|
||||
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
p2i(instruction_address()),
|
||||
callee->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
@@ -465,7 +465,6 @@
|
||||
|
||||
// Initialize frame members (_pc and _sp must be given)
|
||||
inline void setup();
|
||||
const ImmutableOopMap* get_oop_map() const;
|
||||
|
||||
// Constructors
|
||||
|
||||
|
||||
@@ -292,20 +292,6 @@ inline intptr_t* frame::real_fp() const {
|
||||
return fp();
|
||||
}
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
if (_cb == nullptr) return nullptr;
|
||||
if (_cb->oop_maps() != nullptr) {
|
||||
NativePostCallNop* nop = nativePostCallNop_at(_pc);
|
||||
if (nop != nullptr && nop->displacement() != 0) {
|
||||
int slot = ((nop->displacement() >> 24) & 0xff);
|
||||
return _cb->oop_map_for_slot(slot, _pc);
|
||||
}
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline int frame::compiled_frame_stack_argsize() const {
|
||||
Unimplemented();
|
||||
return 0;
|
||||
|
||||
@@ -48,6 +48,9 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||
// The expected size in bytes of a cache line, used to pad data structures.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 256
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#define SUPPORT_RESERVED_STACK_AREA
|
||||
|
||||
#endif // CPU_S390_GLOBALDEFINITIONS_S390_HPP
|
||||
|
||||
@@ -184,4 +184,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Is SIMD sort supported for this CPU?
|
||||
static bool supports_simd_sort(BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // CPU_S390_MATCHER_S390_HPP
|
||||
|
||||
@@ -657,8 +657,8 @@ class NativeGeneralJump: public NativeInstruction {
|
||||
class NativePostCallNop: public NativeInstruction {
|
||||
public:
|
||||
bool check() const { Unimplemented(); return false; }
|
||||
int displacement() const { return 0; }
|
||||
void patch(jint diff) { Unimplemented(); }
|
||||
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const { return false; }
|
||||
bool patch(int32_t oopmap_slot, int32_t cb_offset) { Unimplemented(); return false; }
|
||||
void make_deopt() { Unimplemented(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -755,7 +755,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
return align_up(stk, 2);
|
||||
return stk;
|
||||
}
|
||||
|
||||
int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
|
||||
@@ -410,7 +410,7 @@ class VM_Version: public Abstract_VM_Version {
|
||||
// Override Abstract_VM_Version implementation
|
||||
static void print_platform_virtualization_info(outputStream*);
|
||||
|
||||
// s390 supports fast class initialization checks for static methods.
|
||||
// s390 supports fast class initialization checks
|
||||
static bool supports_fast_class_init_checks() { return true; }
|
||||
|
||||
// CPU feature query functions
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, 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
|
||||
@@ -889,8 +889,8 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
|
||||
assert(which == imm_operand || which == disp32_operand,
|
||||
"which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
|
||||
#else
|
||||
assert((which == call32_operand || which == imm_operand) && is_64bit ||
|
||||
which == narrow_oop_operand && !is_64bit,
|
||||
assert(((which == call32_operand || which == imm_operand) && is_64bit) ||
|
||||
(which == narrow_oop_operand && !is_64bit),
|
||||
"which %d is_64_bit %d ip " INTPTR_FORMAT, which, is_64bit, p2i(ip));
|
||||
#endif // _LP64
|
||||
return ip;
|
||||
@@ -920,6 +920,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
|
||||
case 0x11: // movups
|
||||
case 0x12: // movlps
|
||||
case 0x28: // movaps
|
||||
case 0x29: // movaps
|
||||
case 0x2E: // ucomiss
|
||||
case 0x2F: // comiss
|
||||
case 0x54: // andps
|
||||
@@ -969,7 +970,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
|
||||
assert(which == call32_operand, "jcc has no disp32 or imm");
|
||||
return ip;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
fatal("not handled: 0x0F%2X", 0xFF & *(ip-1));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2845,6 +2846,13 @@ void Assembler::kxorbl(KRegister dst, KRegister src1, KRegister src2) {
|
||||
emit_int16(0x47, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::kxnorwl(KRegister dst, KRegister src1, KRegister src2) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), src1->encoding(), src2->encoding(), VEX_SIMD_NONE, VEX_OPCODE_0F, &attributes);
|
||||
emit_int16(0x46, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::kxorwl(KRegister dst, KRegister src1, KRegister src2) {
|
||||
assert(VM_Version::supports_evex(), "");
|
||||
InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
@@ -7227,7 +7235,7 @@ void Assembler::vxorps(XMMRegister dst, XMMRegister nds, Address src, int vector
|
||||
|
||||
// Integer vector arithmetic
|
||||
void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(VM_Version::supports_avx() && (vector_len == 0) ||
|
||||
assert((VM_Version::supports_avx() && (vector_len == 0)) ||
|
||||
VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
@@ -7235,7 +7243,7 @@ void Assembler::vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int v
|
||||
}
|
||||
|
||||
void Assembler::vphaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
assert(VM_Version::supports_avx() && (vector_len == 0) ||
|
||||
assert((VM_Version::supports_avx() && (vector_len == 0)) ||
|
||||
VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
@@ -10770,7 +10778,7 @@ void Assembler::vpgatherdd(XMMRegister dst, Address src, XMMRegister mask, int v
|
||||
assert(src.isxmmindex(),"expected to be xmm index");
|
||||
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
vex_prefix(src, mask->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8((unsigned char)0x90);
|
||||
emit_operand(dst, src, 0);
|
||||
@@ -10783,7 +10791,7 @@ void Assembler::vpgatherdq(XMMRegister dst, Address src, XMMRegister mask, int v
|
||||
assert(src.isxmmindex(),"expected to be xmm index");
|
||||
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
vex_prefix(src, mask->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8((unsigned char)0x90);
|
||||
emit_operand(dst, src, 0);
|
||||
@@ -10796,7 +10804,7 @@ void Assembler::vgatherdpd(XMMRegister dst, Address src, XMMRegister mask, int v
|
||||
assert(src.isxmmindex(),"expected to be xmm index");
|
||||
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
|
||||
vex_prefix(src, mask->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8((unsigned char)0x92);
|
||||
emit_operand(dst, src, 0);
|
||||
@@ -10809,7 +10817,7 @@ void Assembler::vgatherdps(XMMRegister dst, Address src, XMMRegister mask, int v
|
||||
assert(src.isxmmindex(),"expected to be xmm index");
|
||||
assert(dst != src.xmmindex(), "instruction will #UD if dst and index are the same");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ true);
|
||||
InstructionAttr attributes(vector_len, /* vex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ false, /* uses_vl */ false);
|
||||
vex_prefix(src, mask->encoding(), dst->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8((unsigned char)0x92);
|
||||
emit_operand(dst, src, 0);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user