mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-16 22:39:41 +01:00
Compare commits
277 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
317788ff12 | ||
|
|
6aeabd4bfa | ||
|
|
f52d49925f | ||
|
|
45ee89c4c8 | ||
|
|
ad29642d8f | ||
|
|
ea6493c4e1 | ||
|
|
34f241317e | ||
|
|
1f47294cd3 | ||
|
|
f5187ebf7a | ||
|
|
629bf20f59 | ||
|
|
3559eeca0e | ||
|
|
ad6611a9a3 | ||
|
|
895232fc65 | ||
|
|
5141e1a4f4 | ||
|
|
01adf28c94 | ||
|
|
dc1b0b5f81 | ||
|
|
0e7bc6b092 | ||
|
|
5edeb71e3b | ||
|
|
eda1ab2143 | ||
|
|
d03e7cb87a | ||
|
|
99f90befaf | ||
|
|
fb531cdaf3 | ||
|
|
104d0cb542 | ||
|
|
4f1dcf89b8 | ||
|
|
17744fbfc0 | ||
|
|
d054865200 | ||
|
|
23c39757ec | ||
|
|
f2e56e4c18 | ||
|
|
4e9525ef36 | ||
|
|
b6319f5b42 | ||
|
|
6e2ab84154 | ||
|
|
9b12c0bb19 | ||
|
|
e65e06867e | ||
|
|
0eb2bcd260 | ||
|
|
6ec36d348b | ||
|
|
a99f340e1b | ||
|
|
d854a04231 | ||
|
|
410014377c | ||
|
|
a05d5d2514 | ||
|
|
180d8c1b57 | ||
|
|
dc6255261f | ||
|
|
650de99fc6 | ||
|
|
325cdb7fc5 | ||
|
|
c46bed7292 | ||
|
|
ae85d899d0 | ||
|
|
66d7b0ce8f | ||
|
|
431dcf84e9 | ||
|
|
692edc4879 | ||
|
|
2a1c676e0a | ||
|
|
b0bd0c398e | ||
|
|
e1d1d53cd1 | ||
|
|
aa986be752 | ||
|
|
6a6ff876c5 | ||
|
|
4b774cb46d | ||
|
|
b46aef88b3 | ||
|
|
920a99faeb | ||
|
|
74dca863c2 | ||
|
|
52aa7fe1c9 | ||
|
|
413f852bdb | ||
|
|
11aa6e10c0 | ||
|
|
54430a8722 | ||
|
|
655e9cda3f | ||
|
|
b58e3b600b | ||
|
|
8eaeb6990b | ||
|
|
b60ac710be | ||
|
|
00068a8030 | ||
|
|
1bbbce75c5 | ||
|
|
a5968f9364 | ||
|
|
d36a234c12 | ||
|
|
b6732d6048 | ||
|
|
a26221299e | ||
|
|
eef9813ad4 | ||
|
|
7f9951a934 | ||
|
|
1ae4a6c43e | ||
|
|
b2daf9de30 | ||
|
|
b99be505a5 | ||
|
|
831fe94c75 | ||
|
|
8c8d21db6f | ||
|
|
a4eb57c5ec | ||
|
|
830c4d3b19 | ||
|
|
0a557890a5 | ||
|
|
1f49edd978 | ||
|
|
786833cd1b | ||
|
|
9c91c68d1d | ||
|
|
24244e4121 | ||
|
|
3a8a6e07f2 | ||
|
|
cba09cd10d | ||
|
|
020e3f9591 | ||
|
|
35fe0b1101 | ||
|
|
c9ab330b7b | ||
|
|
3ea82b9ff9 | ||
|
|
b1c9550182 | ||
|
|
c03d445a8c | ||
|
|
b86b2cbc7d | ||
|
|
8df3f3d341 | ||
|
|
b118caf677 | ||
|
|
d34ef196c2 | ||
|
|
811591c5c3 | ||
|
|
355755d35d | ||
|
|
ac81ce51fa | ||
|
|
ed5fc9ad2d | ||
|
|
6700baa505 | ||
|
|
b83bf0717e | ||
|
|
a659479483 | ||
|
|
3500150882 | ||
|
|
7da91533aa | ||
|
|
5f083abafc | ||
|
|
b0f59f6021 | ||
|
|
2596608ba1 | ||
|
|
be8cbfa612 | ||
|
|
f3dd8daaa9 | ||
|
|
4378789029 | ||
|
|
a20b7eb943 | ||
|
|
520c092a65 | ||
|
|
4d696d0d0e | ||
|
|
ee0b8a72c6 | ||
|
|
c09167df60 | ||
|
|
674cc3eeca | ||
|
|
7e91d34f3e | ||
|
|
15f2538943 | ||
|
|
13e32bf166 | ||
|
|
6db1c4f5b9 | ||
|
|
c8b30da7ef | ||
|
|
5ec5a6ea6c | ||
|
|
8e653d394e | ||
|
|
ef7532e7e6 | ||
|
|
b19163b107 | ||
|
|
c7aa10339a | ||
|
|
c55287d197 | ||
|
|
45dcc0e7e2 | ||
|
|
2735140147 | ||
|
|
33dda887d9 | ||
|
|
6f03c7808d | ||
|
|
c4ec983da5 | ||
|
|
bcbdf90fce | ||
|
|
b5970c97bd | ||
|
|
91c5bd550a | ||
|
|
df0165bd69 | ||
|
|
16699a394d | ||
|
|
14000a25e6 | ||
|
|
317daa3c00 | ||
|
|
bb867ed23e | ||
|
|
771253e285 | ||
|
|
63a10e0099 | ||
|
|
828498c54b | ||
|
|
dbf0742bf2 | ||
|
|
019df4d89c | ||
|
|
db2cd1a4e0 | ||
|
|
04c0f8d359 | ||
|
|
4856344668 | ||
|
|
8f8fda7c80 | ||
|
|
db2a5420a2 | ||
|
|
1294d55b19 | ||
|
|
9b386014a0 | ||
|
|
70e2bc876a | ||
|
|
5ea2b64021 | ||
|
|
e534ee9932 | ||
|
|
ba777f6610 | ||
|
|
8a5db916af | ||
|
|
aff25f135a | ||
|
|
e93b10d084 | ||
|
|
8d80778e05 | ||
|
|
fa6ca0bbd1 | ||
|
|
0bcef61a6d | ||
|
|
c432150397 | ||
|
|
af8977e406 | ||
|
|
6d5bf9c801 | ||
|
|
3d54a802e3 | ||
|
|
1d753f1161 | ||
|
|
829b85813a | ||
|
|
87c4b01ea3 | ||
|
|
44e2d499f8 | ||
|
|
c0636734bd | ||
|
|
135661b438 | ||
|
|
afb6a0c2fe | ||
|
|
abb75ba656 | ||
|
|
a655ea4845 | ||
|
|
125d1820f1 | ||
|
|
3f447edf0e | ||
|
|
170ebdc5b7 | ||
|
|
804ce0a239 | ||
|
|
f1a4d1bfde | ||
|
|
94977063ba | ||
|
|
858d2e434d | ||
|
|
3e04e11482 | ||
|
|
177f3404df | ||
|
|
a25e6f6462 | ||
|
|
e65fd45dc7 | ||
|
|
b3e063c2c3 | ||
|
|
a1e8694109 | ||
|
|
2139c8c6e6 | ||
|
|
8f3d0ade11 | ||
|
|
530493fed4 | ||
|
|
1f206e5e12 | ||
|
|
f5e4cd7f0d | ||
|
|
b0a758f218 | ||
|
|
8f0cb57e43 | ||
|
|
37cd8d6ca0 | ||
|
|
8a28a76451 | ||
|
|
0fe1ffdc48 | ||
|
|
a2ad5ca93e | ||
|
|
0bead70651 | ||
|
|
5a60e22bc4 | ||
|
|
b97ed667db | ||
|
|
618732ffc0 | ||
|
|
5627ff2d91 | ||
|
|
ac0e6af8f9 | ||
|
|
153c567a4d | ||
|
|
37d8e05ecc | ||
|
|
8d5a37b060 | ||
|
|
ca4ae8063e | ||
|
|
a62296d8a0 | ||
|
|
6f2169ff69 | ||
|
|
c97d53a952 | ||
|
|
6c01d3b088 | ||
|
|
eecba58c68 | ||
|
|
6abf7b6f22 | ||
|
|
d3083ac054 | ||
|
|
07856fce34 | ||
|
|
5cba2c8461 | ||
|
|
13e062e7a3 | ||
|
|
fd7283be47 | ||
|
|
3f046f6dec | ||
|
|
e27abe8a97 | ||
|
|
f636fcadd7 | ||
|
|
7278d2e8e5 | ||
|
|
84ffe87260 | ||
|
|
79e99bb077 | ||
|
|
45c0600d3a | ||
|
|
6cb1c8f9cf | ||
|
|
002fff39aa | ||
|
|
a1cc8f4e41 | ||
|
|
d328e4e7e2 | ||
|
|
b98114f4a2 | ||
|
|
785ca67e46 | ||
|
|
f5eecc454e | ||
|
|
160148cc7b | ||
|
|
5bd7db034a | ||
|
|
3481252ced | ||
|
|
ef5e744a81 | ||
|
|
969eb1ce24 | ||
|
|
a6bc9b3ba5 | ||
|
|
293fec7e28 | ||
|
|
ca96366c03 | ||
|
|
81b26ba813 | ||
|
|
e0311ecb85 | ||
|
|
c7a489db9e | ||
|
|
3fd551f992 | ||
|
|
282f339406 | ||
|
|
92e1357dfd | ||
|
|
52568bf483 | ||
|
|
e071afbfe4 | ||
|
|
78b155b2b5 | ||
|
|
08c16c384a | ||
|
|
0021dc0410 | ||
|
|
70b4eb249e | ||
|
|
0c6d1b9c8b | ||
|
|
195b36f90b | ||
|
|
f1d90b8b25 | ||
|
|
8a0672c819 | ||
|
|
b2f97131d6 | ||
|
|
683ef14bce | ||
|
|
6901c05c9d | ||
|
|
da8e41a368 | ||
|
|
561c544d85 | ||
|
|
5f5bf1971c | ||
|
|
150def42dd | ||
|
|
d350158e06 | ||
|
|
4ac3395634 | ||
|
|
1f417e7761 | ||
|
|
86aae125f1 | ||
|
|
141aebca38 | ||
|
|
de546d0e03 | ||
|
|
7cd3d7f157 | ||
|
|
848c0c79b6 | ||
|
|
55362e191d | ||
|
|
b054a56571 |
2
.github/workflows/build-alpine-linux.yml
vendored
2
.github/workflows/build-alpine-linux.yml
vendored
@@ -59,7 +59,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-linux:
|
build-linux:
|
||||||
name: build
|
name: build
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
container:
|
container:
|
||||||
image: alpine:3.20
|
image: alpine:3.20
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/build-cross-compile.yml
vendored
2
.github/workflows/build-cross-compile.yml
vendored
@@ -48,7 +48,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-cross-compile:
|
build-cross-compile:
|
||||||
name: build
|
name: build
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|||||||
20
.github/workflows/build-linux.yml
vendored
20
.github/workflows/build-linux.yml
vendored
@@ -75,7 +75,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-linux:
|
build-linux:
|
||||||
name: build
|
name: build
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@@ -115,9 +115,21 @@ jobs:
|
|||||||
if [[ '${{ inputs.apt-architecture }}' != '' ]]; then
|
if [[ '${{ inputs.apt-architecture }}' != '' ]]; then
|
||||||
sudo dpkg --add-architecture ${{ inputs.apt-architecture }}
|
sudo dpkg --add-architecture ${{ inputs.apt-architecture }}
|
||||||
fi
|
fi
|
||||||
sudo apt-get update
|
sudo apt update
|
||||||
sudo apt-get install --only-upgrade apt
|
sudo apt install --only-upgrade apt
|
||||||
sudo apt-get install gcc-${{ inputs.gcc-major-version }}${{ inputs.gcc-package-suffix }} g++-${{ inputs.gcc-major-version }}${{ inputs.gcc-package-suffix }} libxrandr-dev${{ steps.arch.outputs.suffix }} libxtst-dev${{ steps.arch.outputs.suffix }} libcups2-dev${{ steps.arch.outputs.suffix }} libasound2-dev${{ steps.arch.outputs.suffix }} ${{ inputs.apt-extra-packages }}
|
sudo apt install \
|
||||||
|
gcc-${{ inputs.gcc-major-version }}${{ inputs.gcc-package-suffix }} \
|
||||||
|
g++-${{ inputs.gcc-major-version }}${{ inputs.gcc-package-suffix }} \
|
||||||
|
libasound2-dev${{ steps.arch.outputs.suffix }} \
|
||||||
|
libcups2-dev${{ steps.arch.outputs.suffix }} \
|
||||||
|
libfontconfig1-dev${{ steps.arch.outputs.suffix }} \
|
||||||
|
libx11-dev${{ steps.arch.outputs.suffix }} \
|
||||||
|
libxext-dev${{ steps.arch.outputs.suffix }} \
|
||||||
|
libxrandr-dev${{ steps.arch.outputs.suffix }} \
|
||||||
|
libxrender-dev${{ steps.arch.outputs.suffix }} \
|
||||||
|
libxt-dev${{ steps.arch.outputs.suffix }} \
|
||||||
|
libxtst-dev${{ steps.arch.outputs.suffix }} \
|
||||||
|
${{ inputs.apt-extra-packages }}
|
||||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${{ inputs.gcc-major-version }} 100 --slave /usr/bin/g++ g++ /usr/bin/g++-${{ inputs.gcc-major-version }}
|
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${{ inputs.gcc-major-version }} 100 --slave /usr/bin/g++ g++ /usr/bin/g++-${{ inputs.gcc-major-version }}
|
||||||
|
|
||||||
- name: 'Configure'
|
- name: 'Configure'
|
||||||
|
|||||||
6
.github/workflows/main.yml
vendored
6
.github/workflows/main.yml
vendored
@@ -57,7 +57,7 @@ jobs:
|
|||||||
|
|
||||||
prepare:
|
prepare:
|
||||||
name: 'Prepare the run'
|
name: 'Prepare the run'
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
# List of platforms to exclude by default
|
# List of platforms to exclude by default
|
||||||
EXCLUDED_PLATFORMS: 'alpine-linux-x64'
|
EXCLUDED_PLATFORMS: 'alpine-linux-x64'
|
||||||
@@ -405,7 +405,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
platform: linux-x64
|
platform: linux-x64
|
||||||
bootjdk-platform: linux-x64
|
bootjdk-platform: linux-x64
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
dry-run: ${{ needs.prepare.outputs.dry-run == 'true' }}
|
dry-run: ${{ needs.prepare.outputs.dry-run == 'true' }}
|
||||||
debug-suffix: -debug
|
debug-suffix: -debug
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
platform: linux-x64
|
platform: linux-x64
|
||||||
bootjdk-platform: linux-x64
|
bootjdk-platform: linux-x64
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04
|
||||||
dry-run: ${{ needs.prepare.outputs.dry-run == 'true' }}
|
dry-run: ${{ needs.prepare.outputs.dry-run == 'true' }}
|
||||||
static-suffix: "-static"
|
static-suffix: "-static"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[general]
|
[general]
|
||||||
project=jdk
|
project=jdk
|
||||||
jbs=JDK
|
jbs=JDK
|
||||||
version=26
|
version=27
|
||||||
|
|
||||||
[checks]
|
[checks]
|
||||||
error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists,copyright
|
error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists,copyright
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Welcome to the JDK!
|
# Welcome to the JDK!
|
||||||
|
|
||||||
For build instructions please see the
|
For build instructions please see the
|
||||||
[online documentation](https://openjdk.org/groups/build/doc/building.html),
|
[online documentation](https://git.openjdk.org/jdk/blob/master/doc/building.md),
|
||||||
or either of these files:
|
or either of these files:
|
||||||
|
|
||||||
- [doc/building.html](doc/building.html) (html version)
|
- [doc/building.html](doc/building.html) (html version)
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
# directory.
|
# directory.
|
||||||
# - open a terminal program and run these commands:
|
# - open a terminal program and run these commands:
|
||||||
# cd "${JDK_CHECKOUT}"/src/jdk.compiler/share/data/symbols
|
# cd "${JDK_CHECKOUT}"/src/jdk.compiler/share/data/symbols
|
||||||
# bash ../../../../../make/scripts/generate-symbol-data.sh "${JDK_N_INSTALL}"
|
# bash ../../../../../bin/generate-symbol-data.sh "${JDK_N_INSTALL}"
|
||||||
# - this command will generate or update data for "--release N" into the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols
|
# - this command will generate or update data for "--release N" into the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols
|
||||||
# directory, updating all registration necessary. If the goal was to update the data, and there are no
|
# directory, updating all registration necessary. If the goal was to update the data, and there are no
|
||||||
# new or changed files in the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols directory after running this script,
|
# new or changed files in the ${JDK_CHECKOUT}/src/jdk.compiler/share/data/symbols directory after running this script,
|
||||||
|
|||||||
@@ -541,6 +541,11 @@ href="#apple-xcode">Apple Xcode</a> on some strategies to deal with
|
|||||||
this.</p>
|
this.</p>
|
||||||
<p>It is recommended that you use at least macOS 14 and Xcode 15.4, but
|
<p>It is recommended that you use at least macOS 14 and Xcode 15.4, but
|
||||||
earlier versions may also work.</p>
|
earlier versions may also work.</p>
|
||||||
|
<p>Starting with Xcode 26, introduced in macOS 26, the Metal toolchain
|
||||||
|
no longer comes bundled with Xcode, so it needs to be installed
|
||||||
|
separately. This can either be done via the Xcode's Settings/Components
|
||||||
|
UI, or in the command line calling
|
||||||
|
<code>xcodebuild -downloadComponent metalToolchain</code>.</p>
|
||||||
<p>The standard macOS environment contains the basic tooling needed to
|
<p>The standard macOS environment contains the basic tooling needed to
|
||||||
build, but for external libraries a package manager is recommended. The
|
build, but for external libraries a package manager is recommended. The
|
||||||
JDK uses <a href="https://brew.sh/">homebrew</a> in the examples, but
|
JDK uses <a href="https://brew.sh/">homebrew</a> in the examples, but
|
||||||
|
|||||||
@@ -352,6 +352,11 @@ on some strategies to deal with this.
|
|||||||
It is recommended that you use at least macOS 14 and Xcode 15.4, but
|
It is recommended that you use at least macOS 14 and Xcode 15.4, but
|
||||||
earlier versions may also work.
|
earlier versions may also work.
|
||||||
|
|
||||||
|
Starting with Xcode 26, introduced in macOS 26, the Metal toolchain no longer
|
||||||
|
comes bundled with Xcode, so it needs to be installed separately. This can
|
||||||
|
either be done via the Xcode's Settings/Components UI, or in the command line
|
||||||
|
calling `xcodebuild -downloadComponent metalToolchain`.
|
||||||
|
|
||||||
The standard macOS environment contains the basic tooling needed to build, but
|
The standard macOS environment contains the basic tooling needed to build, but
|
||||||
for external libraries a package manager is recommended. The JDK uses
|
for external libraries a package manager is recommended. The JDK uses
|
||||||
[homebrew](https://brew.sh/) in the examples, but feel free to use whatever
|
[homebrew](https://brew.sh/) in the examples, but feel free to use whatever
|
||||||
|
|||||||
@@ -1037,8 +1037,8 @@ running destructors at exit can lead to problems.</p>
|
|||||||
<p>Some of the approaches used in HotSpot to avoid dynamic
|
<p>Some of the approaches used in HotSpot to avoid dynamic
|
||||||
initialization include:</p>
|
initialization include:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><p>Use the <code>Deferred<T></code> class template. Add a call
|
<li><p>Use the <code>DeferredStatic<T></code> class template. Add
|
||||||
to its initialization function at an appropriate place during VM
|
a call to its initialization function at an appropriate place during VM
|
||||||
initialization. The underlying object is never destroyed.</p></li>
|
initialization. The underlying object is never destroyed.</p></li>
|
||||||
<li><p>For objects of class type, use a variable whose value is a
|
<li><p>For objects of class type, use a variable whose value is a
|
||||||
pointer to the class, initialized to <code>nullptr</code>. Provide an
|
pointer to the class, initialized to <code>nullptr</code>. Provide an
|
||||||
|
|||||||
@@ -954,7 +954,7 @@ destructors at exit can lead to problems.
|
|||||||
Some of the approaches used in HotSpot to avoid dynamic initialization
|
Some of the approaches used in HotSpot to avoid dynamic initialization
|
||||||
include:
|
include:
|
||||||
|
|
||||||
* Use the `Deferred<T>` class template. Add a call to its initialization
|
* Use the `DeferredStatic<T>` class template. Add a call to its initialization
|
||||||
function at an appropriate place during VM initialization. The underlying
|
function at an appropriate place during VM initialization. The underlying
|
||||||
object is never destroyed.
|
object is never destroyed.
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,9 @@ cover the new source version</li>
|
|||||||
and
|
and
|
||||||
<code>test/langtools/tools/javac/preview/classReaderTest/Client.preview.out</code>:
|
<code>test/langtools/tools/javac/preview/classReaderTest/Client.preview.out</code>:
|
||||||
update expected messages for preview errors and warnings</li>
|
update expected messages for preview errors and warnings</li>
|
||||||
|
<li><code>test/langtools/tools/javac/versions/Versions.java</code>: add
|
||||||
|
new source version to the set of valid sources and add new enum constant
|
||||||
|
for the new class file version.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -65,4 +65,4 @@ to be updated for a particular release.
|
|||||||
* `test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java`
|
* `test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java`
|
||||||
update annotation processor extended by `javac` tests to cover the new source version
|
update annotation processor extended by `javac` tests to cover the new source version
|
||||||
* `test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out` and `test/langtools/tools/javac/preview/classReaderTest/Client.preview.out`: update expected messages for preview errors and warnings
|
* `test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out` and `test/langtools/tools/javac/preview/classReaderTest/Client.preview.out`: update expected messages for preview errors and warnings
|
||||||
|
* `test/langtools/tools/javac/versions/Versions.java`: add new source version to the set of valid sources and add new enum constant for the new class file version.
|
||||||
|
|||||||
@@ -125,13 +125,6 @@ define SetupBundleFileBody
|
|||||||
&& $(TAR) cf - -$(TAR_INCLUDE_PARAM) $$($1_$$d_LIST_FILE) \
|
&& $(TAR) cf - -$(TAR_INCLUDE_PARAM) $$($1_$$d_LIST_FILE) \
|
||||||
$(TAR_IGNORE_EXIT_VALUE) ) \
|
$(TAR_IGNORE_EXIT_VALUE) ) \
|
||||||
| ( $(CD) $(SUPPORT_OUTPUTDIR)/bundles/$1/$$($1_SUBDIR) && $(TAR) xf - )$$(NEWLINE) )
|
| ( $(CD) $(SUPPORT_OUTPUTDIR)/bundles/$1/$$($1_SUBDIR) && $(TAR) xf - )$$(NEWLINE) )
|
||||||
# Rename stripped pdb files
|
|
||||||
ifeq ($(call isTargetOs, windows)+$(SHIP_DEBUG_SYMBOLS), true+public)
|
|
||||||
for f in `$(FIND) $(SUPPORT_OUTPUTDIR)/bundles/$1/$$($1_SUBDIR) -name "*.stripped.pdb"`; do \
|
|
||||||
$(ECHO) Renaming $$$${f} to $$$${f%stripped.pdb}pdb $(LOG_INFO); \
|
|
||||||
$(MV) $$$${f} $$$${f%stripped.pdb}pdb; \
|
|
||||||
done
|
|
||||||
endif
|
|
||||||
# Unzip any zipped debuginfo files
|
# Unzip any zipped debuginfo files
|
||||||
ifeq ($$($1_UNZIP_DEBUGINFO), true)
|
ifeq ($$($1_UNZIP_DEBUGINFO), true)
|
||||||
for f in `$(FIND) $(SUPPORT_OUTPUTDIR)/bundles/$1/$$($1_SUBDIR) -name "*.diz"`; do \
|
for f in `$(FIND) $(SUPPORT_OUTPUTDIR)/bundles/$1/$$($1_SUBDIR) -name "*.diz"`; do \
|
||||||
@@ -222,14 +215,6 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), )
|
|||||||
ifeq ($(call isTargetOs, windows), true)
|
ifeq ($(call isTargetOs, windows), true)
|
||||||
ifeq ($(SHIP_DEBUG_SYMBOLS), )
|
ifeq ($(SHIP_DEBUG_SYMBOLS), )
|
||||||
JDK_SYMBOLS_EXCLUDE_PATTERN := %.pdb
|
JDK_SYMBOLS_EXCLUDE_PATTERN := %.pdb
|
||||||
else
|
|
||||||
ifeq ($(SHIP_DEBUG_SYMBOLS), public)
|
|
||||||
JDK_SYMBOLS_EXCLUDE_PATTERN := \
|
|
||||||
$(filter-out \
|
|
||||||
%.stripped.pdb, \
|
|
||||||
$(filter %.pdb, $(ALL_JDK_FILES)) \
|
|
||||||
)
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -244,10 +229,7 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), )
|
|||||||
)
|
)
|
||||||
|
|
||||||
JDK_SYMBOLS_BUNDLE_FILES := \
|
JDK_SYMBOLS_BUNDLE_FILES := \
|
||||||
$(filter-out \
|
$(call FindFiles, $(SYMBOLS_IMAGE_DIR))
|
||||||
%.stripped.pdb, \
|
|
||||||
$(call FindFiles, $(SYMBOLS_IMAGE_DIR)) \
|
|
||||||
)
|
|
||||||
|
|
||||||
TEST_DEMOS_BUNDLE_FILES := $(filter $(JDK_DEMOS_IMAGE_HOMEDIR)/demo/%, \
|
TEST_DEMOS_BUNDLE_FILES := $(filter $(JDK_DEMOS_IMAGE_HOMEDIR)/demo/%, \
|
||||||
$(ALL_JDK_DEMOS_FILES))
|
$(ALL_JDK_DEMOS_FILES))
|
||||||
@@ -267,14 +249,6 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), )
|
|||||||
ifeq ($(call isTargetOs, windows), true)
|
ifeq ($(call isTargetOs, windows), true)
|
||||||
ifeq ($(SHIP_DEBUG_SYMBOLS), )
|
ifeq ($(SHIP_DEBUG_SYMBOLS), )
|
||||||
JRE_SYMBOLS_EXCLUDE_PATTERN := %.pdb
|
JRE_SYMBOLS_EXCLUDE_PATTERN := %.pdb
|
||||||
else
|
|
||||||
ifeq ($(SHIP_DEBUG_SYMBOLS), public)
|
|
||||||
JRE_SYMBOLS_EXCLUDE_PATTERN := \
|
|
||||||
$(filter-out \
|
|
||||||
%.stripped.pdb, \
|
|
||||||
$(filter %.pdb, $(ALL_JRE_FILES)) \
|
|
||||||
)
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -282,29 +282,33 @@ else
|
|||||||
endif
|
endif
|
||||||
CMDS_TARGET_SUBDIR := bin
|
CMDS_TARGET_SUBDIR := bin
|
||||||
|
|
||||||
# Param 1 - either JDK or JRE
|
# Copy debug info files into symbols bundle.
|
||||||
|
# In case of Windows and --with-external-symbols-in-bundles=public, take care to remove *.stripped.pdb files
|
||||||
SetupCopyDebuginfo = \
|
SetupCopyDebuginfo = \
|
||||||
$(foreach m, $(ALL_$1_MODULES), \
|
$(foreach m, $(ALL_$1_MODULES), \
|
||||||
|
$(eval dbgfiles := $(call FindDebuginfoFiles, $(SUPPORT_OUTPUTDIR)/modules_libs/$m)) \
|
||||||
|
$(eval dbgfiles := $(if $(filter true+public,$(call isTargetOs,windows)+$(SHIP_DEBUG_SYMBOLS)), \
|
||||||
|
$(filter-out %.stripped.pdb,$(dbgfiles)),$(dbgfiles)) \
|
||||||
|
) \
|
||||||
$(eval $(call SetupCopyFiles, COPY_$1_LIBS_DEBUGINFO_$m, \
|
$(eval $(call SetupCopyFiles, COPY_$1_LIBS_DEBUGINFO_$m, \
|
||||||
SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/$m, \
|
SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/$m, \
|
||||||
DEST := $($1_IMAGE_DIR)/$(LIBS_TARGET_SUBDIR), \
|
DEST := $($1_IMAGE_DIR)/$(LIBS_TARGET_SUBDIR), \
|
||||||
FILES := $(call FindDebuginfoFiles, \
|
FILES := $(dbgfiles), \
|
||||||
$(SUPPORT_OUTPUTDIR)/modules_libs/$m), \
|
|
||||||
)) \
|
)) \
|
||||||
$(eval $1_TARGETS += $$(COPY_$1_LIBS_DEBUGINFO_$m)) \
|
$(eval $1_TARGETS += $$(COPY_$1_LIBS_DEBUGINFO_$m)) \
|
||||||
|
$(eval dbgfiles := $(call FindDebuginfoFiles, $(SUPPORT_OUTPUTDIR)/modules_cmds/$m)) \
|
||||||
|
$(eval dbgfiles := $(if $(filter true+public,$(call isTargetOs,windows)+$(SHIP_DEBUG_SYMBOLS)), \
|
||||||
|
$(filter-out %.stripped.pdb,$(dbgfiles)),$(dbgfiles)) \
|
||||||
|
) \
|
||||||
$(eval $(call SetupCopyFiles, COPY_$1_CMDS_DEBUGINFO_$m, \
|
$(eval $(call SetupCopyFiles, COPY_$1_CMDS_DEBUGINFO_$m, \
|
||||||
SRC := $(SUPPORT_OUTPUTDIR)/modules_cmds/$m, \
|
SRC := $(SUPPORT_OUTPUTDIR)/modules_cmds/$m, \
|
||||||
DEST := $($1_IMAGE_DIR)/$(CMDS_TARGET_SUBDIR), \
|
DEST := $($1_IMAGE_DIR)/$(CMDS_TARGET_SUBDIR), \
|
||||||
FILES := $(call FindDebuginfoFiles, \
|
FILES := $(dbgfiles), \
|
||||||
$(SUPPORT_OUTPUTDIR)/modules_cmds/$m), \
|
|
||||||
)) \
|
)) \
|
||||||
$(eval $1_TARGETS += $$(COPY_$1_CMDS_DEBUGINFO_$m)) \
|
$(eval $1_TARGETS += $$(COPY_$1_CMDS_DEBUGINFO_$m)) \
|
||||||
)
|
)
|
||||||
|
|
||||||
# No space before argument to avoid having to put $(strip ) everywhere in
|
# No space before argument to avoid having to put $(strip ) everywhere in implementation above.
|
||||||
# implementation above.
|
|
||||||
$(call SetupCopyDebuginfo,JDK)
|
|
||||||
$(call SetupCopyDebuginfo,JRE)
|
|
||||||
$(call SetupCopyDebuginfo,SYMBOLS)
|
$(call SetupCopyDebuginfo,SYMBOLS)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|||||||
@@ -873,7 +873,7 @@ define SetupRunJtregTestBody
|
|||||||
$1_JTREG_BASIC_OPTIONS += -testThreadFactoryPath:$$(JTREG_TEST_THREAD_FACTORY_JAR)
|
$1_JTREG_BASIC_OPTIONS += -testThreadFactoryPath:$$(JTREG_TEST_THREAD_FACTORY_JAR)
|
||||||
$1_JTREG_BASIC_OPTIONS += -testThreadFactory:$$(JTREG_TEST_THREAD_FACTORY)
|
$1_JTREG_BASIC_OPTIONS += -testThreadFactory:$$(JTREG_TEST_THREAD_FACTORY)
|
||||||
$1_JTREG_BASIC_OPTIONS += $$(addprefix $$(JTREG_PROBLEM_LIST_PREFIX), $$(wildcard \
|
$1_JTREG_BASIC_OPTIONS += $$(addprefix $$(JTREG_PROBLEM_LIST_PREFIX), $$(wildcard \
|
||||||
$$(addprefix $$($1_TEST_ROOT)/, ProblemList-$$(JTREG_TEST_THREAD_FACTORY).txt) \
|
$$(addprefix $$($1_TEST_ROOT)/, ProblemList-$$(JTREG_TEST_THREAD_FACTORY).txt) \
|
||||||
))
|
))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -881,8 +881,8 @@ define SetupRunJtregTestBody
|
|||||||
AGENT := $$(LIBRARY_PREFIX)JvmtiStressAgent$$(SHARED_LIBRARY_SUFFIX)=$$(JTREG_JVMTI_STRESS_AGENT)
|
AGENT := $$(LIBRARY_PREFIX)JvmtiStressAgent$$(SHARED_LIBRARY_SUFFIX)=$$(JTREG_JVMTI_STRESS_AGENT)
|
||||||
$1_JTREG_BASIC_OPTIONS += -javaoption:'-agentpath:$(TEST_IMAGE_DIR)/hotspot/jtreg/native/$$(AGENT)'
|
$1_JTREG_BASIC_OPTIONS += -javaoption:'-agentpath:$(TEST_IMAGE_DIR)/hotspot/jtreg/native/$$(AGENT)'
|
||||||
$1_JTREG_BASIC_OPTIONS += $$(addprefix $$(JTREG_PROBLEM_LIST_PREFIX), $$(wildcard \
|
$1_JTREG_BASIC_OPTIONS += $$(addprefix $$(JTREG_PROBLEM_LIST_PREFIX), $$(wildcard \
|
||||||
$$(addprefix $$($1_TEST_ROOT)/, ProblemList-jvmti-stress-agent.txt) \
|
$$(addprefix $$($1_TEST_ROOT)/, ProblemList-jvmti-stress-agent.txt) \
|
||||||
))
|
))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
@@ -1092,7 +1092,7 @@ define SetupRunJtregTestBody
|
|||||||
$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR) \
|
$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR) \
|
||||||
$$($1_TEST_TMP_DIR))
|
$$($1_TEST_TMP_DIR))
|
||||||
$$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/jtreg, \
|
$$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/jtreg, \
|
||||||
$$(COV_ENVIRONMENT) $$($1_COMMAND_LINE) \
|
$$(COV_ENVIRONMENT) $$($1_COMMAND_LINE) \
|
||||||
)
|
)
|
||||||
|
|
||||||
$1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/text/stats.txt
|
$1_RESULT_FILE := $$($1_TEST_RESULTS_DIR)/text/stats.txt
|
||||||
@@ -1102,11 +1102,11 @@ define SetupRunJtregTestBody
|
|||||||
$$(call LogWarn, Test report is stored in $$(strip \
|
$$(call LogWarn, Test report is stored in $$(strip \
|
||||||
$$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
|
$$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
|
||||||
|
|
||||||
# Read jtreg documentation to learn on the test stats categories:
|
# Read jtreg documentation to learn on the test stats categories:
|
||||||
# https://github.com/openjdk/jtreg/blob/master/src/share/doc/javatest/regtest/faq.md#what-do-all-those-numbers-in-the-test-results-line-mean
|
# https://github.com/openjdk/jtreg/blob/master/src/share/doc/javatest/regtest/faq.md#what-do-all-those-numbers-in-the-test-results-line-mean
|
||||||
# In jtreg, "skipped:" category accounts for tests that threw jtreg.SkippedException at runtime.
|
# In jtreg, "skipped:" category accounts for tests that threw jtreg.SkippedException at runtime.
|
||||||
# At the same time these tests contribute to "passed:" tests.
|
# At the same time these tests contribute to "passed:" tests.
|
||||||
# In here we don't want that and so we substract number of "skipped:" from "passed:".
|
# In here we don't want that and so we substract number of "skipped:" from "passed:".
|
||||||
|
|
||||||
$$(if $$(wildcard $$($1_RESULT_FILE)), \
|
$$(if $$(wildcard $$($1_RESULT_FILE)), \
|
||||||
$$(eval $1_PASSED_AND_RUNTIME_SKIPPED := $$(shell $$(AWK) '{ gsub(/[,;]/, ""); \
|
$$(eval $1_PASSED_AND_RUNTIME_SKIPPED := $$(shell $$(AWK) '{ gsub(/[,;]/, ""); \
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ TOOL_GENERATEEXTRAPROPERTIES = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_too
|
|||||||
build.tools.generateextraproperties.GenerateExtraProperties
|
build.tools.generateextraproperties.GenerateExtraProperties
|
||||||
|
|
||||||
TOOL_GENERATECASEFOLDING = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
TOOL_GENERATECASEFOLDING = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
||||||
build.tools.generatecharacter.CaseFolding
|
build.tools.generatecharacter.GenerateCaseFolding
|
||||||
|
|
||||||
TOOL_MAKEZIPREPRODUCIBLE = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
TOOL_MAKEZIPREPRODUCIBLE = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
||||||
build.tools.makezipreproducible.MakeZipReproducible
|
build.tools.makezipreproducible.MakeZipReproducible
|
||||||
|
|||||||
@@ -353,7 +353,12 @@ AC_DEFUN_ONCE([BASIC_SETUP_DEVKIT],
|
|||||||
[set up toolchain on Mac OS using a path to an Xcode installation])])
|
[set up toolchain on Mac OS using a path to an Xcode installation])])
|
||||||
|
|
||||||
UTIL_DEPRECATED_ARG_WITH(sys-root)
|
UTIL_DEPRECATED_ARG_WITH(sys-root)
|
||||||
UTIL_DEPRECATED_ARG_WITH(tools-dir)
|
|
||||||
|
AC_ARG_WITH([tools-dir], [AS_HELP_STRING([--with-tools-dir],
|
||||||
|
[Point to a nonstandard Visual Studio installation location on Windows by
|
||||||
|
specifying any existing directory 2 or 3 levels below the installation
|
||||||
|
root.])]
|
||||||
|
)
|
||||||
|
|
||||||
if test "x$with_xcode_path" != x; then
|
if test "x$with_xcode_path" != x; then
|
||||||
if test "x$OPENJDK_BUILD_OS" = "xmacosx"; then
|
if test "x$OPENJDK_BUILD_OS" = "xmacosx"; then
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS],
|
|||||||
FLAGS_SETUP_LDFLAGS_CPU_DEP([TARGET])
|
FLAGS_SETUP_LDFLAGS_CPU_DEP([TARGET])
|
||||||
|
|
||||||
# Setup the build toolchain
|
# Setup the build toolchain
|
||||||
FLAGS_SETUP_LDFLAGS_CPU_DEP([BUILD], [OPENJDK_BUILD_])
|
FLAGS_SETUP_LDFLAGS_CPU_DEP([BUILD], [OPENJDK_BUILD_], [BUILD_])
|
||||||
|
|
||||||
AC_SUBST(ADLC_LDFLAGS)
|
AC_SUBST(ADLC_LDFLAGS)
|
||||||
])
|
])
|
||||||
@@ -52,11 +52,6 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
|
|||||||
# add --no-as-needed to disable default --as-needed link flag on some GCC toolchains
|
# add --no-as-needed to disable default --as-needed link flag on some GCC toolchains
|
||||||
# add --icf=all (Identical Code Folding — merges identical functions)
|
# add --icf=all (Identical Code Folding — merges identical functions)
|
||||||
BASIC_LDFLAGS="-Wl,-z,defs -Wl,-z,relro -Wl,-z,now -Wl,--no-as-needed -Wl,--exclude-libs,ALL"
|
BASIC_LDFLAGS="-Wl,-z,defs -Wl,-z,relro -Wl,-z,now -Wl,--no-as-needed -Wl,--exclude-libs,ALL"
|
||||||
if test "x$LINKER_TYPE" = "xgold"; then
|
|
||||||
if test x$DEBUG_LEVEL = xrelease; then
|
|
||||||
BASIC_LDFLAGS="$BASIC_LDFLAGS -Wl,--icf=all"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Linux : remove unused code+data in link step
|
# Linux : remove unused code+data in link step
|
||||||
if test "x$ENABLE_LINKTIME_GC" = xtrue; then
|
if test "x$ENABLE_LINKTIME_GC" = xtrue; then
|
||||||
@@ -68,7 +63,7 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
BASIC_LDFLAGS_JVM_ONLY=""
|
BASIC_LDFLAGS_JVM_ONLY=""
|
||||||
LDFLAGS_LTO="-flto=auto -fuse-linker-plugin -fno-strict-aliasing"
|
LDFLAGS_LTO="-flto=auto -fuse-linker-plugin -fno-strict-aliasing $DEBUG_PREFIX_CFLAGS"
|
||||||
|
|
||||||
LDFLAGS_CXX_PARTIAL_LINKING="$MACHINE_FLAG -r"
|
LDFLAGS_CXX_PARTIAL_LINKING="$MACHINE_FLAG -r"
|
||||||
|
|
||||||
@@ -76,7 +71,7 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
|
|||||||
BASIC_LDFLAGS_JVM_ONLY="-mno-omit-leaf-frame-pointer -mstack-alignment=16 \
|
BASIC_LDFLAGS_JVM_ONLY="-mno-omit-leaf-frame-pointer -mstack-alignment=16 \
|
||||||
-fPIC"
|
-fPIC"
|
||||||
|
|
||||||
LDFLAGS_LTO="-flto=auto -fuse-linker-plugin -fno-strict-aliasing"
|
LDFLAGS_LTO="-flto=auto -fuse-linker-plugin -fno-strict-aliasing $DEBUG_PREFIX_CFLAGS"
|
||||||
LDFLAGS_CXX_PARTIAL_LINKING="$MACHINE_FLAG -r"
|
LDFLAGS_CXX_PARTIAL_LINKING="$MACHINE_FLAG -r"
|
||||||
|
|
||||||
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||||
@@ -108,6 +103,9 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
|
|||||||
|
|
||||||
# Setup OS-dependent LDFLAGS
|
# Setup OS-dependent LDFLAGS
|
||||||
if test "x$OPENJDK_TARGET_OS" = xmacosx && test "x$TOOLCHAIN_TYPE" = xclang; then
|
if test "x$OPENJDK_TARGET_OS" = xmacosx && test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||||
|
if test x$DEBUG_LEVEL = xrelease; then
|
||||||
|
BASIC_LDFLAGS_JDK_ONLY="$BASIC_LDFLAGS_JDK_ONLY -Wl,-dead_strip"
|
||||||
|
fi
|
||||||
# FIXME: We should really generalize SetSharedLibraryOrigin instead.
|
# FIXME: We should really generalize SetSharedLibraryOrigin instead.
|
||||||
OS_LDFLAGS_JVM_ONLY="-Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
|
OS_LDFLAGS_JVM_ONLY="-Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
|
||||||
OS_LDFLAGS="-mmacosx-version-min=$MACOSX_VERSION_MIN -Wl,-reproducible"
|
OS_LDFLAGS="-mmacosx-version-min=$MACOSX_VERSION_MIN -Wl,-reproducible"
|
||||||
@@ -166,7 +164,8 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
|
|||||||
################################################################################
|
################################################################################
|
||||||
# $1 - Either BUILD or TARGET to pick the correct OS/CPU variables to check
|
# $1 - Either BUILD or TARGET to pick the correct OS/CPU variables to check
|
||||||
# conditionals against.
|
# conditionals against.
|
||||||
# $2 - Optional prefix for each variable defined.
|
# $2 - Optional prefix for each variable defined (OPENJDK_BUILD_ or nothing).
|
||||||
|
# $3 - Optional prefix for toolchain variables (BUILD_ or nothing).
|
||||||
AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP],
|
AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP],
|
||||||
[
|
[
|
||||||
# Setup CPU-dependent basic LDFLAGS. These can differ between the target and
|
# Setup CPU-dependent basic LDFLAGS. These can differ between the target and
|
||||||
@@ -200,6 +199,12 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP],
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "x${$3LD_TYPE}" = "xgold"; then
|
||||||
|
if test x$DEBUG_LEVEL = xrelease; then
|
||||||
|
$1_CPU_LDFLAGS="${$1_CPU_LDFLAGS} -Wl,--icf=all"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Export variables according to old definitions, prefix with $2 if present.
|
# Export variables according to old definitions, prefix with $2 if present.
|
||||||
LDFLAGS_JDK_COMMON="$BASIC_LDFLAGS $BASIC_LDFLAGS_JDK_ONLY \
|
LDFLAGS_JDK_COMMON="$BASIC_LDFLAGS $BASIC_LDFLAGS_JDK_ONLY \
|
||||||
$OS_LDFLAGS $DEBUGLEVEL_LDFLAGS_JDK_ONLY ${$2EXTRA_LDFLAGS}"
|
$OS_LDFLAGS $DEBUGLEVEL_LDFLAGS_JDK_ONLY ${$2EXTRA_LDFLAGS}"
|
||||||
|
|||||||
@@ -516,7 +516,7 @@ AC_DEFUN([TOOLCHAIN_EXTRACT_LD_VERSION],
|
|||||||
if [ [[ "$LINKER_VERSION_STRING" == *gold* ]] ]; then
|
if [ [[ "$LINKER_VERSION_STRING" == *gold* ]] ]; then
|
||||||
[ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \
|
[ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \
|
||||||
$SED -e 's/.* \([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*) .*/\1/'` ]
|
$SED -e 's/.* \([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*) .*/\1/'` ]
|
||||||
LINKER_TYPE=gold
|
$1_TYPE=gold
|
||||||
else
|
else
|
||||||
[ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \
|
[ LINKER_VERSION_NUMBER=`$ECHO $LINKER_VERSION_STRING | \
|
||||||
$SED -e 's/.* \([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*/\1/'` ]
|
$SED -e 's/.* \([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*/\1/'` ]
|
||||||
|
|||||||
@@ -229,6 +229,14 @@ define SetupLinkerFlags
|
|||||||
# TOOLCHAIN_TYPE plus OPENJDK_TARGET_OS
|
# TOOLCHAIN_TYPE plus OPENJDK_TARGET_OS
|
||||||
ifeq ($$($1_LINK_TIME_OPTIMIZATION), true)
|
ifeq ($$($1_LINK_TIME_OPTIMIZATION), true)
|
||||||
$1_EXTRA_LDFLAGS += $(LDFLAGS_LTO)
|
$1_EXTRA_LDFLAGS += $(LDFLAGS_LTO)
|
||||||
|
# Instruct the ld64 linker not to delete the temporary object file
|
||||||
|
# generated during Link Time Optimization
|
||||||
|
ifeq ($(call isTargetOs, macosx), true)
|
||||||
|
$1_EXTRA_LDFLAGS += -Wl,-object_path_lto,$$($1_OBJECT_DIR)/$$($1_NAME)_lto_helper.o
|
||||||
|
endif
|
||||||
|
ifeq ($(TOOLCHAIN_TYPE), microsoft)
|
||||||
|
$1_EXTRA_LDFLAGS += -LTCGOUT:$$($1_OBJECT_DIR)/$$($1_NAME).iobj
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$1_EXTRA_LDFLAGS += $$($1_LDFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_LDFLAGS_$(OPENJDK_TARGET_OS)) \
|
$1_EXTRA_LDFLAGS += $$($1_LDFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_LDFLAGS_$(OPENJDK_TARGET_OS)) \
|
||||||
|
|||||||
@@ -1192,8 +1192,8 @@ var getJibProfilesDependencies = function (input, common) {
|
|||||||
server: "jpg",
|
server: "jpg",
|
||||||
product: "jcov",
|
product: "jcov",
|
||||||
version: "3.0",
|
version: "3.0",
|
||||||
build_number: "3",
|
build_number: "5",
|
||||||
file: "bundles/jcov-3.0+3.zip",
|
file: "bundles/jcov-3.0+5.zip",
|
||||||
environment_name: "JCOV_HOME",
|
environment_name: "JCOV_HOME",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -26,17 +26,17 @@
|
|||||||
# Default version, product, and vendor information to use,
|
# Default version, product, and vendor information to use,
|
||||||
# unless overridden by configure
|
# unless overridden by configure
|
||||||
|
|
||||||
DEFAULT_VERSION_FEATURE=26
|
DEFAULT_VERSION_FEATURE=27
|
||||||
DEFAULT_VERSION_INTERIM=0
|
DEFAULT_VERSION_INTERIM=0
|
||||||
DEFAULT_VERSION_UPDATE=0
|
DEFAULT_VERSION_UPDATE=0
|
||||||
DEFAULT_VERSION_PATCH=0
|
DEFAULT_VERSION_PATCH=0
|
||||||
DEFAULT_VERSION_EXTRA1=0
|
DEFAULT_VERSION_EXTRA1=0
|
||||||
DEFAULT_VERSION_EXTRA2=0
|
DEFAULT_VERSION_EXTRA2=0
|
||||||
DEFAULT_VERSION_EXTRA3=0
|
DEFAULT_VERSION_EXTRA3=0
|
||||||
DEFAULT_VERSION_DATE=2026-03-17
|
DEFAULT_VERSION_DATE=2026-09-15
|
||||||
DEFAULT_VERSION_CLASSFILE_MAJOR=70 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
DEFAULT_VERSION_CLASSFILE_MAJOR=71 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
||||||
DEFAULT_VERSION_CLASSFILE_MINOR=0
|
DEFAULT_VERSION_CLASSFILE_MINOR=0
|
||||||
DEFAULT_VERSION_DOCS_API_SINCE=11
|
DEFAULT_VERSION_DOCS_API_SINCE=11
|
||||||
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="25 26"
|
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="25 26 27"
|
||||||
DEFAULT_JDK_SOURCE_TARGET_VERSION=26
|
DEFAULT_JDK_SOURCE_TARGET_VERSION=27
|
||||||
DEFAULT_PROMOTED_VERSION_PRE=ea
|
DEFAULT_PROMOTED_VERSION_PRE=ea
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ ifeq ($(call check-jvm-feature, compiler2), true)
|
|||||||
ifeq ($(HOTSPOT_TARGET_CPU_ARCH), aarch64)
|
ifeq ($(HOTSPOT_TARGET_CPU_ARCH), aarch64)
|
||||||
AD_SRC_FILES += $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \
|
AD_SRC_FILES += $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \
|
||||||
$d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/$(HOTSPOT_TARGET_CPU_ARCH)_vector.ad \
|
$d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/$(HOTSPOT_TARGET_CPU_ARCH)_vector.ad \
|
||||||
|
$d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/$(HOTSPOT_TARGET_CPU_ARCH)_atomic.ad \
|
||||||
)))
|
)))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -151,6 +151,12 @@ JVM_STRIPFLAGS ?= $(STRIPFLAGS)
|
|||||||
# This source set is reused so save in cache.
|
# This source set is reused so save in cache.
|
||||||
$(call FillFindCache, $(JVM_SRC_DIRS))
|
$(call FillFindCache, $(JVM_SRC_DIRS))
|
||||||
|
|
||||||
|
ifeq ($(SHIP_DEBUG_SYMBOLS), full)
|
||||||
|
CFLAGS_SHIP_DEBUGINFO := -DSHIP_DEBUGINFO_FULL
|
||||||
|
else ifeq ($(SHIP_DEBUG_SYMBOLS), public)
|
||||||
|
CFLAGS_SHIP_DEBUGINFO := -DSHIP_DEBUGINFO_PUBLIC
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(call isTargetOs, windows), true)
|
ifeq ($(call isTargetOs, windows), true)
|
||||||
ifeq ($(STATIC_LIBS), true)
|
ifeq ($(STATIC_LIBS), true)
|
||||||
WIN_EXPORT_FILE := $(JVM_OUTPUTDIR)/static-win-exports.def
|
WIN_EXPORT_FILE := $(JVM_OUTPUTDIR)/static-win-exports.def
|
||||||
@@ -158,10 +164,6 @@ ifeq ($(call isTargetOs, windows), true)
|
|||||||
WIN_EXPORT_FILE := $(JVM_OUTPUTDIR)/win-exports.def
|
WIN_EXPORT_FILE := $(JVM_OUTPUTDIR)/win-exports.def
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(SHIP_DEBUG_SYMBOLS), public)
|
|
||||||
CFLAGS_STRIPPED_DEBUGINFO := -DHAS_STRIPPED_DEBUGINFO
|
|
||||||
endif
|
|
||||||
|
|
||||||
JVM_LDFLAGS += -def:$(WIN_EXPORT_FILE)
|
JVM_LDFLAGS += -def:$(WIN_EXPORT_FILE)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -187,7 +189,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJVM, \
|
|||||||
CFLAGS := $(JVM_CFLAGS), \
|
CFLAGS := $(JVM_CFLAGS), \
|
||||||
abstract_vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
|
abstract_vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
|
||||||
arguments.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
|
arguments.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \
|
||||||
whitebox.cpp_CXXFLAGS := $(CFLAGS_STRIPPED_DEBUGINFO), \
|
whitebox.cpp_CXXFLAGS := $(CFLAGS_SHIP_DEBUGINFO), \
|
||||||
DISABLED_WARNINGS_gcc := $(DISABLED_WARNINGS_gcc), \
|
DISABLED_WARNINGS_gcc := $(DISABLED_WARNINGS_gcc), \
|
||||||
DISABLED_WARNINGS_gcc_ad_$(HOTSPOT_TARGET_CPU_ARCH).cpp := nonnull, \
|
DISABLED_WARNINGS_gcc_ad_$(HOTSPOT_TARGET_CPU_ARCH).cpp := nonnull, \
|
||||||
DISABLED_WARNINGS_gcc_bytecodeInterpreter.cpp := unused-label, \
|
DISABLED_WARNINGS_gcc_bytecodeInterpreter.cpp := unused-label, \
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package build.tools.generatecharacter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class CaseFolding {
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Throwable {
|
|
||||||
if (args.length != 3) {
|
|
||||||
System.err.println("Usage: java CaseFolding TemplateFile CaseFolding.txt CaseFolding.java");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
var templateFile = Paths.get(args[0]);
|
|
||||||
var caseFoldingTxt = Paths.get(args[1]);
|
|
||||||
var genSrcFile = Paths.get(args[2]);
|
|
||||||
var supportedTypes = "^.*; [CTS]; .*$";
|
|
||||||
var caseFoldingEntries = Files.lines(caseFoldingTxt)
|
|
||||||
.filter(line -> !line.startsWith("#") && line.matches(supportedTypes))
|
|
||||||
.map(line -> {
|
|
||||||
String[] cols = line.split("; ");
|
|
||||||
return new String[] {cols[0], cols[1], cols[2]};
|
|
||||||
})
|
|
||||||
.filter(cols -> {
|
|
||||||
// the folding case doesn't map back to the original char.
|
|
||||||
var cp1 = Integer.parseInt(cols[0], 16);
|
|
||||||
var cp2 = Integer.parseInt(cols[2], 16);
|
|
||||||
return Character.toUpperCase(cp2) != cp1 && Character.toLowerCase(cp2) != cp1;
|
|
||||||
})
|
|
||||||
.map(cols -> String.format(" entry(0x%s, 0x%s)", cols[0], cols[2]))
|
|
||||||
.collect(Collectors.joining(",\n", "", ""));
|
|
||||||
|
|
||||||
// hack, hack, hack! the logic does not pick 0131. just add manually to support 'I's.
|
|
||||||
// 0049; T; 0131; # LATIN CAPITAL LETTER I
|
|
||||||
final String T_0x0131_0x49 = String.format(" entry(0x%04x, 0x%04x),\n", 0x0131, 0x49);
|
|
||||||
|
|
||||||
// Generate .java file
|
|
||||||
Files.write(
|
|
||||||
genSrcFile,
|
|
||||||
Files.lines(templateFile)
|
|
||||||
.map(line -> line.contains("%%%Entries") ? T_0x0131_0x49 + caseFoldingEntries : line)
|
|
||||||
.collect(Collectors.toList()),
|
|
||||||
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package build.tools.generatecharacter;
|
||||||
|
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class GenerateCaseFolding {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Throwable {
|
||||||
|
if (args.length != 3) {
|
||||||
|
System.err.println("Usage: java GenerateCaseFolding TemplateFile CaseFolding.txt CaseFolding.java");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
var templateFile = Paths.get(args[0]);
|
||||||
|
var caseFoldingTxt = Paths.get(args[1]);
|
||||||
|
var genSrcFile = Paths.get(args[2]);
|
||||||
|
|
||||||
|
// java.lang
|
||||||
|
var supportedTypes = "^.*; [CF]; .*$"; // full/1:M case folding
|
||||||
|
String[][] caseFoldings = Files.lines(caseFoldingTxt)
|
||||||
|
.filter(line -> !line.startsWith("#") && line.matches(supportedTypes))
|
||||||
|
.map(line -> {
|
||||||
|
var fields = line.split("; ");
|
||||||
|
var cp = fields[0];
|
||||||
|
fields = fields[2].trim().split(" ");
|
||||||
|
var folding = new String[fields.length + 1];
|
||||||
|
folding[0] = cp;
|
||||||
|
System.arraycopy(fields, 0, folding, 1, fields.length);
|
||||||
|
return folding;
|
||||||
|
})
|
||||||
|
.toArray(size -> new String[size][]);
|
||||||
|
|
||||||
|
// util.regex
|
||||||
|
var expandedSupportedTypes = "^.*; [CTS]; .*$";
|
||||||
|
var expanded_caseFoldingEntries = Files.lines(caseFoldingTxt)
|
||||||
|
.filter(line -> !line.startsWith("#") && line.matches(expandedSupportedTypes))
|
||||||
|
.map(line -> {
|
||||||
|
String[] cols = line.split("; ");
|
||||||
|
return new String[]{cols[0], cols[1], cols[2]};
|
||||||
|
})
|
||||||
|
.filter(cols -> {
|
||||||
|
// the folding case doesn't map back to the original char.
|
||||||
|
var cp1 = Integer.parseInt(cols[0], 16);
|
||||||
|
var cp2 = Integer.parseInt(cols[2], 16);
|
||||||
|
return Character.toUpperCase(cp2) != cp1 && Character.toLowerCase(cp2) != cp1;
|
||||||
|
})
|
||||||
|
.map(cols -> String.format(" entry(0x%s, 0x%s)", cols[0], cols[2]))
|
||||||
|
.collect(Collectors.joining(",\n", "", ""));
|
||||||
|
|
||||||
|
// hack, hack, hack! the logic does not pick 0131. just add manually to support 'I's.
|
||||||
|
// 0049; T; 0131; # LATIN CAPITAL LETTER I
|
||||||
|
final String T_0x0131_0x49 = String.format(" entry(0x%04x, 0x%04x),\n", 0x0131, 0x49);
|
||||||
|
|
||||||
|
Files.write(
|
||||||
|
genSrcFile,
|
||||||
|
Files.lines(templateFile)
|
||||||
|
.map(line -> line.contains("%%%Entries") ? genFoldingEntries(caseFoldings) : line)
|
||||||
|
.map(line -> line.contains("%%%Expanded_Case_Map_Entries") ? T_0x0131_0x49 + expanded_caseFoldingEntries : line)
|
||||||
|
.collect(Collectors.toList()),
|
||||||
|
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long foldingToLong(String[] folding) {
|
||||||
|
int cp = Integer.parseInt(folding[0], 16);
|
||||||
|
long value = (long)Integer.parseInt(folding[1], 16);
|
||||||
|
if (!Character.isSupplementaryCodePoint(cp) && folding.length != 2) {
|
||||||
|
var shift = 16;
|
||||||
|
for (int j = 2; j < folding.length; j++) {
|
||||||
|
value |= (long)Integer.parseInt(folding[j], 16) << shift;
|
||||||
|
shift <<= 1;
|
||||||
|
}
|
||||||
|
value = value | (long) (folding.length - 1) << 48;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String genFoldingEntries(String[][] foldings) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(" private static final int[] CASE_FOLDING_CPS = {\n");
|
||||||
|
int width = 10;
|
||||||
|
for (int i = 0; i < foldings.length; i++) {
|
||||||
|
if (i % width == 0)
|
||||||
|
sb.append(" ");
|
||||||
|
sb.append(String.format("0X%s", foldings[i][0]));
|
||||||
|
if (i < foldings.length - 1)
|
||||||
|
sb.append(", ");
|
||||||
|
if (i % width == width - 1 || i == foldings.length - 1)
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
sb.append(" };\n\n");
|
||||||
|
|
||||||
|
sb.append(" private static final long[] CASE_FOLDING_VALUES = {\n");
|
||||||
|
width = 6;
|
||||||
|
for (int i = 0; i < foldings.length; i++) {
|
||||||
|
if (i % width == 0)
|
||||||
|
sb.append(" "); // indent
|
||||||
|
sb.append(String.format("0x%013xL", foldingToLong(foldings[i])));
|
||||||
|
if (i < foldings.length - 1)
|
||||||
|
sb.append(", ");
|
||||||
|
if (i % width == width - 1 || i == foldings.length - 1) {
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append(" };\n");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -120,3 +120,25 @@ $(INTPOLY_GEN_DONE): $(INTPLOY_HEADER) $(BUILD_TOOLS_JDK)
|
|||||||
TARGETS += $(INTPOLY_GEN_DONE)
|
TARGETS += $(INTPOLY_GEN_DONE)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
|
RELEASE_FILE_TEMPLATE := $(TOPDIR)/src/java.base/share/classes/jdk/internal/misc/resources/release.txt.template
|
||||||
|
RELEASE_FILE_TARGET := $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/jdk/internal/misc/resources/release.txt
|
||||||
|
|
||||||
|
RELEASE_FILE_VARDEPS := $(COMPANY_NAME) $(VERSION_STRING) $(VERSION_DATE)
|
||||||
|
RELEASE_FILE_VARDEPS_FILE := $(call DependOnVariable, RELEASE_FILE_VARDEPS, \
|
||||||
|
$(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/jlink_release_txt.vardeps)
|
||||||
|
|
||||||
|
$(eval $(call SetupTextFileProcessing, BUILD_RELEASE_FILE, \
|
||||||
|
SOURCE_FILES := $(RELEASE_FILE_TEMPLATE), \
|
||||||
|
OUTPUT_FILE := $(RELEASE_FILE_TARGET), \
|
||||||
|
REPLACEMENTS := \
|
||||||
|
@@COMPANY_NAME@@ => $(COMPANY_NAME) ; \
|
||||||
|
@@VERSION_STRING@@ => $(VERSION_STRING) ; \
|
||||||
|
@@VERSION_DATE@@ => $(VERSION_DATE) , \
|
||||||
|
))
|
||||||
|
|
||||||
|
$(BUILD_RELEASE_FILE): $(RELEASE_FILE_VARDEPS_FILE)
|
||||||
|
|
||||||
|
TARGETS += $(BUILD_RELEASE_FILE)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
DOCLINT += -Xdoclint:all/protected \
|
DOCLINT += -Xdoclint:all/protected \
|
||||||
'-Xdoclint/package:java.*,javax.*'
|
'-Xdoclint/package:java.*,javax.*'
|
||||||
JAVAC_FLAGS += -XDstringConcat=inline
|
JAVAC_FLAGS += -XDstringConcat=inline
|
||||||
COPY += .icu .dat .spp .nrm content-types.properties \
|
COPY += .icu .dat .spp .nrm .txt content-types.properties \
|
||||||
hijrah-config-Hijrah-umalqura_islamic-umalqura.properties
|
hijrah-config-Hijrah-umalqura_islamic-umalqura.properties
|
||||||
CLEAN += intrinsic.properties
|
CLEAN += intrinsic.properties
|
||||||
|
|
||||||
|
|||||||
@@ -72,5 +72,22 @@ TARGETS += $(GENSRC_CHARACTERDATA)
|
|||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
GENSRC_STRINGCASEFOLDING := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/lang/CaseFolding.java
|
||||||
|
|
||||||
|
STRINGCASEFOLDING_TEMPLATE := $(MODULE_SRC)/share/classes/jdk/internal/lang/CaseFolding.java.template
|
||||||
|
CASEFOLDINGTXT := $(MODULE_SRC)/share/data/unicodedata/CaseFolding.txt
|
||||||
|
|
||||||
|
$(GENSRC_STRINGCASEFOLDING): $(BUILD_TOOLS_JDK) $(STRINGCASEFOLDING_TEMPLATE) $(CASEFOLDINGTXT)
|
||||||
|
$(call LogInfo, Generating $@)
|
||||||
|
$(call MakeTargetDir)
|
||||||
|
$(TOOL_GENERATECASEFOLDING) \
|
||||||
|
$(STRINGCASEFOLDING_TEMPLATE) \
|
||||||
|
$(CASEFOLDINGTXT) \
|
||||||
|
$(GENSRC_STRINGCASEFOLDING)
|
||||||
|
|
||||||
|
TARGETS += $(GENSRC_STRINGCASEFOLDING)
|
||||||
|
|
||||||
|
|
||||||
endif # include guard
|
endif # include guard
|
||||||
include MakeIncludeEnd.gmk
|
include MakeIncludeEnd.gmk
|
||||||
|
|||||||
@@ -50,22 +50,5 @@ TARGETS += $(GENSRC_INDICCONJUNCTBREAK)
|
|||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
GENSRC_CASEFOLDING := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/jdk/internal/util/regex/CaseFolding.java
|
|
||||||
|
|
||||||
CASEFOLDINGTEMP := $(MODULE_SRC)/share/classes/jdk/internal/util/regex/CaseFolding.java.template
|
|
||||||
CASEFOLDINGTXT := $(MODULE_SRC)/share/data/unicodedata/CaseFolding.txt
|
|
||||||
|
|
||||||
$(GENSRC_CASEFOLDING): $(BUILD_TOOLS_JDK) $(CASEFOLDINGTEMP) $(CASEFOLDINGTXT)
|
|
||||||
$(call LogInfo, Generating $@)
|
|
||||||
$(call MakeTargetDir)
|
|
||||||
$(TOOL_GENERATECASEFOLDING) \
|
|
||||||
$(CASEFOLDINGTEMP) \
|
|
||||||
$(CASEFOLDINGTXT) \
|
|
||||||
$(GENSRC_CASEFOLDING)
|
|
||||||
|
|
||||||
TARGETS += $(GENSRC_CASEFOLDING)
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
endif # include guard
|
endif # include guard
|
||||||
include MakeIncludeEnd.gmk
|
include MakeIncludeEnd.gmk
|
||||||
|
|||||||
@@ -164,6 +164,24 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
|
|||||||
|
|
||||||
ifeq ($(USE_EXTERNAL_LIBPNG), false)
|
ifeq ($(USE_EXTERNAL_LIBPNG), false)
|
||||||
LIBSPLASHSCREEN_HEADER_DIRS += libsplashscreen/libpng
|
LIBSPLASHSCREEN_HEADER_DIRS += libsplashscreen/libpng
|
||||||
|
LIBSPLASHSCREEN_CFLAGS += -DPNG_NO_MMX_CODE -DPNG_ARM_NEON_OPT=0
|
||||||
|
-DPNG_ARM_NEON_IMPLEMENTATION=0 -DPNG_LOONGARCH_LSX_OPT=0
|
||||||
|
|
||||||
|
ifeq ($(call isTargetOs, linux)+$(call isTargetCpuArch, ppc), true+true)
|
||||||
|
LIBSPLASHSCREEN_CFLAGS += -DPNG_POWERPC_VSX_OPT=0
|
||||||
|
endif
|
||||||
|
|
||||||
|
# The libpng bundled with jdk is a reduced version which does not
|
||||||
|
# contain .png_init_filter_functions_vsx.
|
||||||
|
# Therefore we need to disable PNG_POWERPC_VSX_OPT explicitly by setting
|
||||||
|
# it to 0. If this define is not set, it would be automatically set to 2,
|
||||||
|
# because
|
||||||
|
# "#if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)"
|
||||||
|
# expands to true. This would results in the fact that
|
||||||
|
# .png_init_filter_functions_vsx is needed in libpng.
|
||||||
|
ifeq ($(call isTargetOs, aix), true)
|
||||||
|
LIBSPLASHSCREEN_CFLAGS += -DPNG_POWERPC_VSX_OPT=0
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
LIBSPLASHSCREEN_EXCLUDES += libpng
|
LIBSPLASHSCREEN_EXCLUDES += libpng
|
||||||
endif
|
endif
|
||||||
@@ -176,25 +194,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
|
|||||||
LIBSPLASHSCREEN_STATIC_LIB_EXCLUDE_OBJS += $(LIBZIP_OBJS)
|
LIBSPLASHSCREEN_STATIC_LIB_EXCLUDE_OBJS += $(LIBZIP_OBJS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIBSPLASHSCREEN_CFLAGS += -DSPLASHSCREEN -DPNG_NO_MMX_CODE \
|
LIBSPLASHSCREEN_CFLAGS += -DSPLASHSCREEN
|
||||||
-DPNG_ARM_NEON_OPT=0 -DPNG_ARM_NEON_IMPLEMENTATION=0 \
|
|
||||||
-DPNG_LOONGARCH_LSX_OPT=0
|
|
||||||
|
|
||||||
ifeq ($(call isTargetOs, linux)+$(call isTargetCpuArch, ppc), true+true)
|
|
||||||
LIBSPLASHSCREEN_CFLAGS += -DPNG_POWERPC_VSX_OPT=0
|
|
||||||
endif
|
|
||||||
|
|
||||||
# The external libpng submitted in the jdk is a reduced version
|
|
||||||
# which does not contain .png_init_filter_functions_vsx.
|
|
||||||
# Therefore we need to disable PNG_POWERPC_VSX_OPT explicitly by setting
|
|
||||||
# it to 0. If this define is not set, it would be automatically set to 2,
|
|
||||||
# because
|
|
||||||
# "#if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)"
|
|
||||||
# expands to true. This would results in the fact that
|
|
||||||
# .png_init_filter_functions_vsx is needed in libpng.
|
|
||||||
ifeq ($(call isTargetOs, aix), true)
|
|
||||||
LIBSPLASHSCREEN_CFLAGS += -DPNG_POWERPC_VSX_OPT=0
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(call isTargetOs, macosx), true)
|
ifeq ($(call isTargetOs, macosx), true)
|
||||||
# libsplashscreen on macosx does not use the unix code
|
# libsplashscreen on macosx does not use the unix code
|
||||||
@@ -237,7 +237,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
|
|||||||
DISABLED_WARNINGS_gcc_dgif_lib.c := sign-compare, \
|
DISABLED_WARNINGS_gcc_dgif_lib.c := sign-compare, \
|
||||||
DISABLED_WARNINGS_gcc_jcmaster.c := implicit-fallthrough, \
|
DISABLED_WARNINGS_gcc_jcmaster.c := implicit-fallthrough, \
|
||||||
DISABLED_WARNINGS_gcc_jdphuff.c := shift-negative-value, \
|
DISABLED_WARNINGS_gcc_jdphuff.c := shift-negative-value, \
|
||||||
DISABLED_WARNINGS_gcc_png.c := maybe-uninitialized unused-function, \
|
DISABLED_WARNINGS_gcc_png.c := maybe-uninitialized, \
|
||||||
DISABLED_WARNINGS_gcc_pngerror.c := maybe-uninitialized, \
|
DISABLED_WARNINGS_gcc_pngerror.c := maybe-uninitialized, \
|
||||||
DISABLED_WARNINGS_gcc_splashscreen_gfx_impl.c := implicit-fallthrough \
|
DISABLED_WARNINGS_gcc_splashscreen_gfx_impl.c := implicit-fallthrough \
|
||||||
maybe-uninitialized, \
|
maybe-uninitialized, \
|
||||||
@@ -248,7 +248,6 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
|
|||||||
DISABLED_WARNINGS_clang := deprecated-non-prototype, \
|
DISABLED_WARNINGS_clang := deprecated-non-prototype, \
|
||||||
DISABLED_WARNINGS_clang_dgif_lib.c := sign-compare, \
|
DISABLED_WARNINGS_clang_dgif_lib.c := sign-compare, \
|
||||||
DISABLED_WARNINGS_clang_gzwrite.c := format-nonliteral, \
|
DISABLED_WARNINGS_clang_gzwrite.c := format-nonliteral, \
|
||||||
DISABLED_WARNINGS_clang_png.c := unused-function, \
|
|
||||||
DISABLED_WARNINGS_clang_splashscreen_impl.c := sign-compare \
|
DISABLED_WARNINGS_clang_splashscreen_impl.c := sign-compare \
|
||||||
unused-but-set-variable unused-function, \
|
unused-but-set-variable unused-function, \
|
||||||
DISABLED_WARNINGS_clang_splashscreen_png.c := \
|
DISABLED_WARNINGS_clang_splashscreen_png.c := \
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
909
src/hotspot/cpu/aarch64/aarch64_atomic.ad
Normal file
909
src/hotspot/cpu/aarch64/aarch64_atomic.ad
Normal file
@@ -0,0 +1,909 @@
|
|||||||
|
// Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
// Copyright (c) 2016, 2021, Red Hat Inc. All rights reserved.
|
||||||
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
//
|
||||||
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU General Public License version 2 only, as
|
||||||
|
// published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
// version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
// accompanied this code).
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License version
|
||||||
|
// 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
// or visit www.oracle.com if you need additional information or have any
|
||||||
|
// questions.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
// BEGIN This file is automatically generated. Do not edit --------------
|
||||||
|
|
||||||
|
// Sundry CAS operations. Note that release is always true,
|
||||||
|
// regardless of the memory ordering of the CAS. This is because we
|
||||||
|
// need the volatile case to be sequentially consistent but there is
|
||||||
|
// no trailing StoreLoad barrier emitted by C2. Unfortunately we
|
||||||
|
// can't check the type of memory ordering here, so we always emit a
|
||||||
|
// STLXR.
|
||||||
|
|
||||||
|
// This section is generated from aarch64_atomic_ad.m4
|
||||||
|
|
||||||
|
|
||||||
|
instruct compareAndExchangeB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgb $res = $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::byte, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
__ sxtbw($res$$Register, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgs $res = $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::halfword, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
__ sxthw($res$$Register, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw $res = $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg $res = $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
|
||||||
|
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||||
|
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg $res = $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (CompareAndExchangeB mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::byte, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
__ sxtbw($res$$Register, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (CompareAndExchangeS mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::halfword, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
__ sxthw($res$$Register, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (CompareAndExchangeI mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeLAcq(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg_acq $res = $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
|
||||||
|
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (CompareAndSwapB mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgb $res = $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::byte, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (CompareAndSwapS mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgs $res = $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::halfword, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (CompareAndSwapI mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw $res = $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (CompareAndSwapL mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg $res = $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
|
||||||
|
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set res (CompareAndSwapN mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw $res = $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||||
|
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg $res = $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (CompareAndSwapB mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgb_acq $res = $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::byte, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (CompareAndSwapS mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgs_acq $res = $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::halfword, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (CompareAndSwapI mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw_acq $res = $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (CompareAndSwapL mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg_acq $res = $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set res (CompareAndSwapN mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw_acq $res = $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
|
||||||
|
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg_acq $res = $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ false, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgb_weak $res = $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::byte, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapS(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgs_weak $res = $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::halfword, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapI(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw_weak $res = $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
|
||||||
|
match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg_weak $res = $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
|
||||||
|
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw_weak $res = $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||||
|
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg_weak $res = $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ false, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapBAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgb_acq_weak $res = $mem, $oldval, $newval\t# (byte) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::byte, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapSAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (WeakCompareAndSwapS mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgs_acq_weak $res = $mem, $oldval, $newval\t# (short) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::halfword, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapIAcq(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (WeakCompareAndSwapI mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw_acq_weak $res = $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapLAcq(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg_acq_weak $res = $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchgw_acq_weak $res = $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::word, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
|
||||||
|
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg_acq_weak $res = $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::xword, /*acquire*/ true, /*release*/ true,
|
||||||
|
/*weak*/ true, noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndSetI(indirect mem, iRegI newval, iRegINoSp oldval) %{
|
||||||
|
match(Set oldval (GetAndSetI mem newval));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
format %{ "atomic_xchgw $oldval, $newval, [$mem]" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_xchgw($oldval$$Register, $newval$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndSetL(indirect mem, iRegL newval, iRegLNoSp oldval) %{
|
||||||
|
match(Set oldval (GetAndSetL mem newval));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
format %{ "atomic_xchg $oldval, $newval, [$mem]" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_xchg($oldval$$Register, $newval$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndSetN(indirect mem, iRegN newval, iRegNNoSp oldval) %{
|
||||||
|
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set oldval (GetAndSetN mem newval));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
format %{ "atomic_xchgw $oldval, $newval, [$mem]" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_xchgw($oldval$$Register, $newval$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndSetP(indirect mem, iRegP newval, iRegPNoSp oldval) %{
|
||||||
|
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set oldval (GetAndSetP mem newval));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
format %{ "atomic_xchg $oldval, $newval, [$mem]" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_xchg($oldval$$Register, $newval$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndSetIAcq(indirect mem, iRegI newval, iRegINoSp oldval) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set oldval (GetAndSetI mem newval));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
format %{ "atomic_xchgw_acq $oldval, $newval, [$mem]" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_xchgalw($oldval$$Register, $newval$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndSetLAcq(indirect mem, iRegL newval, iRegLNoSp oldval) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set oldval (GetAndSetL mem newval));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
format %{ "atomic_xchg_acq $oldval, $newval, [$mem]" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_xchgal($oldval$$Register, $newval$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndSetNAcq(indirect mem, iRegN newval, iRegNNoSp oldval) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);
|
||||||
|
match(Set oldval (GetAndSetN mem newval));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
format %{ "atomic_xchgw_acq $oldval, $newval, [$mem]" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_xchgalw($oldval$$Register, $newval$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndSetPAcq(indirect mem, iRegP newval, iRegPNoSp oldval) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
|
||||||
|
match(Set oldval (GetAndSetP mem newval));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
format %{ "atomic_xchg_acq $oldval, $newval, [$mem]" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_xchgal($oldval$$Register, $newval$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddI(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
|
||||||
|
match(Set newval (GetAndAddI mem incr));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST+1);
|
||||||
|
format %{ "get_and_addI $newval, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addw($newval$$Register, $incr$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddIAcq(indirect mem, iRegINoSp newval, iRegIorL2I incr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set newval (GetAndAddI mem incr));
|
||||||
|
ins_cost(VOLATILE_REF_COST+1);
|
||||||
|
format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addalw($newval$$Register, $incr$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddINoRes(indirect mem, Universe dummy, iRegIorL2I incr) %{
|
||||||
|
predicate(n->as_LoadStore()->result_not_used());
|
||||||
|
match(Set dummy (GetAndAddI mem incr));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
format %{ "get_and_addI noreg, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addw(noreg, $incr$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddIAcqNoRes(indirect mem, Universe dummy, iRegIorL2I incr) %{
|
||||||
|
predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set dummy (GetAndAddI mem incr));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
format %{ "get_and_addI_acq noreg, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addalw(noreg, $incr$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddIConst(indirect mem, iRegINoSp newval, immIAddSub incr) %{
|
||||||
|
match(Set newval (GetAndAddI mem incr));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST+1);
|
||||||
|
format %{ "get_and_addI $newval, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addw($newval$$Register, $incr$$constant, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddIAcqConst(indirect mem, iRegINoSp newval, immIAddSub incr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set newval (GetAndAddI mem incr));
|
||||||
|
ins_cost(VOLATILE_REF_COST+1);
|
||||||
|
format %{ "get_and_addI_acq $newval, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addalw($newval$$Register, $incr$$constant, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddINoResConst(indirect mem, Universe dummy, immIAddSub incr) %{
|
||||||
|
predicate(n->as_LoadStore()->result_not_used());
|
||||||
|
match(Set dummy (GetAndAddI mem incr));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
format %{ "get_and_addI noreg, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addw(noreg, $incr$$constant, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddIAcqNoResConst(indirect mem, Universe dummy, immIAddSub incr) %{
|
||||||
|
predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set dummy (GetAndAddI mem incr));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
format %{ "get_and_addI_acq noreg, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addalw(noreg, $incr$$constant, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddL(indirect mem, iRegLNoSp newval, iRegL incr) %{
|
||||||
|
match(Set newval (GetAndAddL mem incr));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST+1);
|
||||||
|
format %{ "get_and_addL $newval, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_add($newval$$Register, $incr$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddLAcq(indirect mem, iRegLNoSp newval, iRegL incr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set newval (GetAndAddL mem incr));
|
||||||
|
ins_cost(VOLATILE_REF_COST+1);
|
||||||
|
format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addal($newval$$Register, $incr$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddLNoRes(indirect mem, Universe dummy, iRegL incr) %{
|
||||||
|
predicate(n->as_LoadStore()->result_not_used());
|
||||||
|
match(Set dummy (GetAndAddL mem incr));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
format %{ "get_and_addL noreg, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_add(noreg, $incr$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddLAcqNoRes(indirect mem, Universe dummy, iRegL incr) %{
|
||||||
|
predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set dummy (GetAndAddL mem incr));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
format %{ "get_and_addL_acq noreg, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addal(noreg, $incr$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddLConst(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
|
||||||
|
match(Set newval (GetAndAddL mem incr));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST+1);
|
||||||
|
format %{ "get_and_addL $newval, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_add($newval$$Register, $incr$$constant, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddLAcqConst(indirect mem, iRegLNoSp newval, immLAddSub incr) %{
|
||||||
|
predicate(needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set newval (GetAndAddL mem incr));
|
||||||
|
ins_cost(VOLATILE_REF_COST+1);
|
||||||
|
format %{ "get_and_addL_acq $newval, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addal($newval$$Register, $incr$$constant, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddLNoResConst(indirect mem, Universe dummy, immLAddSub incr) %{
|
||||||
|
predicate(n->as_LoadStore()->result_not_used());
|
||||||
|
match(Set dummy (GetAndAddL mem incr));
|
||||||
|
ins_cost(2*VOLATILE_REF_COST);
|
||||||
|
format %{ "get_and_addL noreg, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_add(noreg, $incr$$constant, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct getAndAddLAcqNoResConst(indirect mem, Universe dummy, immLAddSub incr) %{
|
||||||
|
predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));
|
||||||
|
match(Set dummy (GetAndAddL mem incr));
|
||||||
|
ins_cost(VOLATILE_REF_COST);
|
||||||
|
format %{ "get_and_addL_acq noreg, [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_addal(noreg, $incr$$constant, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}
|
||||||
246
src/hotspot/cpu/aarch64/aarch64_atomic_ad.m4
Normal file
246
src/hotspot/cpu/aarch64/aarch64_atomic_ad.m4
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
// Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
// Copyright (c) 2016, 2021, Red Hat Inc. All rights reserved.
|
||||||
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
//
|
||||||
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU General Public License version 2 only, as
|
||||||
|
// published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
// version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
// accompanied this code).
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License version
|
||||||
|
// 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
//
|
||||||
|
// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
// or visit www.oracle.com if you need additional information or have any
|
||||||
|
// questions.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
// BEGIN This file is automatically generated. Do not edit --------------
|
||||||
|
|
||||||
|
// Sundry CAS operations. Note that release is always true,
|
||||||
|
// regardless of the memory ordering of the CAS. This is because we
|
||||||
|
// need the volatile case to be sequentially consistent but there is
|
||||||
|
// no trailing StoreLoad barrier emitted by C2. Unfortunately we
|
||||||
|
// can't check the type of memory ordering here, so we always emit a
|
||||||
|
// STLXR.
|
||||||
|
|
||||||
|
// This section is generated from aarch64_atomic_ad.m4
|
||||||
|
|
||||||
|
dnl Return Arg1 with two spaces before it. We need this because m4
|
||||||
|
dnl strips leading spaces from macro args.
|
||||||
|
define(`INDENT', ` $1')dnl
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
dnl ====================== CompareAndExchange*
|
||||||
|
dnl
|
||||||
|
define(`CAE_INSN1',
|
||||||
|
`
|
||||||
|
instruct compareAndExchange$1$7(iReg$2NoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
|
||||||
|
ifelse($7,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),`dnl')
|
||||||
|
match(Set res (CompareAndExchange$1 mem (Binary oldval newval)));
|
||||||
|
ins_cost(`'ifelse($7,Acq,,2*)VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg$5`'ifelse($7,Acq,_acq,) $res = $mem, $oldval, $newval\t# ($3) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::$4, /*acquire*/ ifelse($7,Acq,true,false), /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
__ $6($res$$Register, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}')dnl
|
||||||
|
define(`CAE_INSN2',
|
||||||
|
`
|
||||||
|
instruct compareAndExchange$1$6(iReg$2NoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
|
||||||
|
ifelse($1$6,PAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));),
|
||||||
|
$1$6,NAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);),
|
||||||
|
$1,P,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
||||||
|
$1,N,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
||||||
|
$6,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),
|
||||||
|
`dnl')
|
||||||
|
match(Set res (CompareAndExchange$1 mem (Binary oldval newval)));
|
||||||
|
ins_cost(`'ifelse($6,Acq,,2*)VOLATILE_REF_COST);
|
||||||
|
effect(TEMP_DEF res, KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg$5`'ifelse($6,Acq,_acq,) $res = $mem, $oldval, $newval\t# ($3) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
|
||||||
|
/*weak*/ false, $res$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}')dnl
|
||||||
|
dnl
|
||||||
|
CAE_INSN1(B, I, byte, byte, b, sxtbw, )
|
||||||
|
CAE_INSN1(S, I, short, halfword, s, sxthw, )
|
||||||
|
CAE_INSN2(I, I, int, word, w, , )
|
||||||
|
CAE_INSN2(L, L, long, xword, , , )
|
||||||
|
CAE_INSN2(N, N, narrow oop, word, w, , )
|
||||||
|
CAE_INSN2(P, P, ptr, xword, , , )
|
||||||
|
dnl
|
||||||
|
CAE_INSN1(B, I, byte, byte, b, sxtbw, Acq)
|
||||||
|
CAE_INSN1(S, I, short, halfword, s, sxthw, Acq)
|
||||||
|
CAE_INSN2(I, I, int, word, w, Acq)
|
||||||
|
CAE_INSN2(L, L, long, xword, , Acq)
|
||||||
|
CAE_INSN2(N, N, narrow oop, word, w, Acq)
|
||||||
|
CAE_INSN2(P, P, ptr, xword, , Acq)
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
dnl ====================== (Weak)CompareAndSwap*
|
||||||
|
dnl
|
||||||
|
define(`CAS_INSN1',
|
||||||
|
`
|
||||||
|
instruct ifelse($7,Weak,'weakCompare`,'compare`)AndSwap$1$6(iRegINoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
|
||||||
|
ifelse($6,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),`dnl')
|
||||||
|
match(Set res ($7CompareAndSwap$1 mem (Binary oldval newval)));
|
||||||
|
ins_cost(`'ifelse($6,Acq,,2*)VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg$5`'ifelse($6,Acq,_acq,)`'ifelse($7,Weak,_weak) $res = $mem, $oldval, $newval\t# ($3) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
|
||||||
|
/*weak*/ ifelse($7,Weak,true,false), noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}')dnl
|
||||||
|
dnl
|
||||||
|
define(`CAS_INSN2',
|
||||||
|
`
|
||||||
|
instruct ifelse($7,Weak,'weakCompare`,'compare`)AndSwap$1$6(iRegINoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
|
||||||
|
ifelse($1$6,PAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));),
|
||||||
|
$1$6,NAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);),
|
||||||
|
$1,P,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
||||||
|
$1,N,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
||||||
|
$6,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),
|
||||||
|
`dnl')
|
||||||
|
match(Set res ($7CompareAndSwap$1 mem (Binary oldval newval)));
|
||||||
|
ins_cost(`'ifelse($6,Acq,,2*)VOLATILE_REF_COST);
|
||||||
|
effect(KILL cr);
|
||||||
|
format %{
|
||||||
|
"cmpxchg$5`'ifelse($6,Acq,_acq,)`'ifelse($7,Weak,_weak) $res = $mem, $oldval, $newval\t# ($3) if $mem == $oldval then $mem <-- $newval"
|
||||||
|
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||||
|
%}
|
||||||
|
ins_encode %{
|
||||||
|
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||||
|
Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
|
||||||
|
/*weak*/ ifelse($7,Weak,true,false), noreg);
|
||||||
|
__ csetw($res$$Register, Assembler::EQ);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_slow);
|
||||||
|
%}')dnl
|
||||||
|
dnl
|
||||||
|
CAS_INSN1(B, I, byte, byte, b, , )
|
||||||
|
CAS_INSN1(S, I, short, halfword, s, , )
|
||||||
|
CAS_INSN2(I, I, int, word, w, , )
|
||||||
|
CAS_INSN2(L, L, long, xword, , , )
|
||||||
|
CAS_INSN2(N, N, narrow oop, word, w, , )
|
||||||
|
CAS_INSN2(P, P, ptr, xword, , , )
|
||||||
|
dnl
|
||||||
|
CAS_INSN1(B, I, byte, byte, b, Acq, )
|
||||||
|
CAS_INSN1(S, I, short, halfword, s, Acq, )
|
||||||
|
CAS_INSN2(I, I, int, word, w, Acq, )
|
||||||
|
CAS_INSN2(L, L, long, xword, , Acq, )
|
||||||
|
CAS_INSN2(N, N, narrow oop, word, w, Acq, )
|
||||||
|
CAS_INSN2(P, P, ptr, xword, , Acq, )
|
||||||
|
dnl
|
||||||
|
CAS_INSN1(B, I, byte, byte, b, , Weak)
|
||||||
|
CAS_INSN1(S, I, short, halfword, s, , Weak)
|
||||||
|
CAS_INSN2(I, I, int, word, w, , Weak)
|
||||||
|
CAS_INSN2(L, L, long, xword, , , Weak)
|
||||||
|
CAS_INSN2(N, N, narrow oop, word, w, , Weak)
|
||||||
|
CAS_INSN2(P, P, ptr, xword, , , Weak)
|
||||||
|
dnl
|
||||||
|
CAS_INSN1(B, I, byte, byte, b, Acq, Weak)
|
||||||
|
CAS_INSN1(S, I, short, halfword, s, Acq, Weak)
|
||||||
|
CAS_INSN2(I, I, int, word, w, Acq, Weak)
|
||||||
|
CAS_INSN2(L, L, long, xword, , Acq, Weak)
|
||||||
|
CAS_INSN2(N, N, narrow oop, word, w, Acq, Weak)
|
||||||
|
CAS_INSN2(P, P, ptr, xword, , Acq, Weak)
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
dnl ====================== GetAndSet*
|
||||||
|
dnl
|
||||||
|
define(`GAS_INSN1',
|
||||||
|
`
|
||||||
|
instruct getAndSet$1$3(indirect mem, iReg$1 newval, iReg$1NoSp oldval) %{
|
||||||
|
ifelse($1$3,PAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));),
|
||||||
|
$1$3,NAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);),
|
||||||
|
$1,P,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
||||||
|
$1,N,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
||||||
|
$3,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),
|
||||||
|
`dnl')
|
||||||
|
match(Set oldval (GetAndSet$1 mem newval));
|
||||||
|
ins_cost(`'ifelse($3,Acq,,2*)VOLATILE_REF_COST);
|
||||||
|
format %{ "atomic_xchg$2`'ifelse($3,Acq,_acq) $oldval, $newval, [$mem]" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_xchg`'ifelse($3,Acq,al)$2($oldval$$Register, $newval$$Register, as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}')dnl
|
||||||
|
dnl
|
||||||
|
GAS_INSN1(I, w, )
|
||||||
|
GAS_INSN1(L, , )
|
||||||
|
GAS_INSN1(N, w, )
|
||||||
|
GAS_INSN1(P, , )
|
||||||
|
dnl
|
||||||
|
GAS_INSN1(I, w, Acq)
|
||||||
|
GAS_INSN1(L, , Acq)
|
||||||
|
GAS_INSN1(N, w, Acq)
|
||||||
|
GAS_INSN1(P, , Acq)
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
dnl ====================== GetAndAdd*
|
||||||
|
dnl
|
||||||
|
define(`GAA_INSN1',
|
||||||
|
`
|
||||||
|
instruct getAndAdd$1$4$5$6(indirect mem, `'ifelse($5,NoRes,Universe dummy,iReg$1NoSp newval), `'ifelse($6,Const,imm$1AddSub incr,iReg$2 incr)) %{
|
||||||
|
ifelse($4$5,AcqNoRes,INDENT(predicate(n->as_LoadStore()->result_not_used() && needs_acquiring_load_exclusive(n));),
|
||||||
|
$5,NoRes,INDENT(predicate(n->as_LoadStore()->result_not_used());),
|
||||||
|
$4,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),
|
||||||
|
`dnl')
|
||||||
|
match(Set ifelse($5,NoRes,dummy,newval) (GetAndAdd$1 mem incr));
|
||||||
|
ins_cost(`'ifelse($4,Acq,,2*)VOLATILE_REF_COST`'ifelse($5,NoRes,,+1));
|
||||||
|
format %{ "get_and_add$1`'ifelse($4,Acq,_acq) `'ifelse($5,NoRes,noreg,$newval), [$mem], $incr" %}
|
||||||
|
ins_encode %{
|
||||||
|
__ atomic_add`'ifelse($4,Acq,al)$3(`'ifelse($5,NoRes,noreg,$newval$$Register), `'ifelse($6,Const,$incr$$constant,$incr$$Register), as_Register($mem$$base));
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_serial);
|
||||||
|
%}')dnl
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
GAA_INSN1(I, IorL2I, w, , , )
|
||||||
|
GAA_INSN1(I, IorL2I, w, Acq, , )
|
||||||
|
GAA_INSN1(I, IorL2I, w, , NoRes, )
|
||||||
|
GAA_INSN1(I, IorL2I, w, Acq, NoRes, )
|
||||||
|
GAA_INSN1(I, I, w, , , Const)
|
||||||
|
GAA_INSN1(I, I, w, Acq, , Const)
|
||||||
|
GAA_INSN1(I, I, w, , NoRes, Const)
|
||||||
|
GAA_INSN1(I, I, w, Acq, NoRes, Const)
|
||||||
|
dnl
|
||||||
|
GAA_INSN1(L, L, , , , )
|
||||||
|
GAA_INSN1(L, L, , Acq, , )
|
||||||
|
GAA_INSN1(L, L, , , NoRes, )
|
||||||
|
GAA_INSN1(L, L, , Acq, NoRes, )
|
||||||
|
GAA_INSN1(L, L, , , , Const)
|
||||||
|
GAA_INSN1(L, L, , Acq, , Const)
|
||||||
|
GAA_INSN1(L, L, , , NoRes, Const)
|
||||||
|
GAA_INSN1(L, L, , Acq, NoRes, Const)
|
||||||
|
dnl
|
||||||
@@ -346,8 +346,14 @@ source %{
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
|
bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
|
||||||
// Only SVE has partial vector operations
|
// 1. Only SVE requires partial vector operations.
|
||||||
if (UseSVE == 0) {
|
// 2. The vector size in bytes must be smaller than MaxVectorSize.
|
||||||
|
// 3. Predicated vectors have a mask input, which guarantees that
|
||||||
|
// out-of-bounds lanes remain inactive.
|
||||||
|
int length_in_bytes = vt->length_in_bytes();
|
||||||
|
if (UseSVE == 0 ||
|
||||||
|
length_in_bytes == MaxVectorSize ||
|
||||||
|
node->is_predicated_vector()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,21 +376,22 @@ source %{
|
|||||||
return !node->in(1)->is_Con();
|
return !node->in(1)->is_Con();
|
||||||
case Op_LoadVector:
|
case Op_LoadVector:
|
||||||
case Op_StoreVector:
|
case Op_StoreVector:
|
||||||
// We use NEON load/store instructions if the vector length is <= 128 bits.
|
|
||||||
return vt->length_in_bytes() > 16;
|
|
||||||
case Op_AddReductionVI:
|
case Op_AddReductionVI:
|
||||||
case Op_AddReductionVL:
|
case Op_AddReductionVL:
|
||||||
// We may prefer using NEON instructions rather than SVE partial operations.
|
// For these ops, we prefer using NEON instructions rather than SVE
|
||||||
return !VM_Version::use_neon_for_vector(vt->length_in_bytes());
|
// predicated instructions for better performance.
|
||||||
|
return !VM_Version::use_neon_for_vector(length_in_bytes);
|
||||||
case Op_MinReductionV:
|
case Op_MinReductionV:
|
||||||
case Op_MaxReductionV:
|
case Op_MaxReductionV:
|
||||||
// For BYTE/SHORT/INT/FLOAT/DOUBLE types, we may prefer using NEON
|
// For BYTE/SHORT/INT/FLOAT/DOUBLE types, we prefer using NEON
|
||||||
// instructions rather than SVE partial operations.
|
// instructions rather than SVE predicated instructions for
|
||||||
|
// better performance.
|
||||||
return vt->element_basic_type() == T_LONG ||
|
return vt->element_basic_type() == T_LONG ||
|
||||||
!VM_Version::use_neon_for_vector(vt->length_in_bytes());
|
!VM_Version::use_neon_for_vector(length_in_bytes);
|
||||||
default:
|
default:
|
||||||
// For other ops whose vector size is smaller than the max vector size, a
|
// For other ops whose vector size is smaller than the max vector
|
||||||
// full-sized unpredicated operation does not impact the final vector result.
|
// size, a full-sized unpredicated operation does not impact the
|
||||||
|
// vector result.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,8 +336,14 @@ source %{
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
|
bool Matcher::vector_needs_partial_operations(Node* node, const TypeVect* vt) {
|
||||||
// Only SVE has partial vector operations
|
// 1. Only SVE requires partial vector operations.
|
||||||
if (UseSVE == 0) {
|
// 2. The vector size in bytes must be smaller than MaxVectorSize.
|
||||||
|
// 3. Predicated vectors have a mask input, which guarantees that
|
||||||
|
// out-of-bounds lanes remain inactive.
|
||||||
|
int length_in_bytes = vt->length_in_bytes();
|
||||||
|
if (UseSVE == 0 ||
|
||||||
|
length_in_bytes == MaxVectorSize ||
|
||||||
|
node->is_predicated_vector()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,21 +366,22 @@ source %{
|
|||||||
return !node->in(1)->is_Con();
|
return !node->in(1)->is_Con();
|
||||||
case Op_LoadVector:
|
case Op_LoadVector:
|
||||||
case Op_StoreVector:
|
case Op_StoreVector:
|
||||||
// We use NEON load/store instructions if the vector length is <= 128 bits.
|
|
||||||
return vt->length_in_bytes() > 16;
|
|
||||||
case Op_AddReductionVI:
|
case Op_AddReductionVI:
|
||||||
case Op_AddReductionVL:
|
case Op_AddReductionVL:
|
||||||
// We may prefer using NEON instructions rather than SVE partial operations.
|
// For these ops, we prefer using NEON instructions rather than SVE
|
||||||
return !VM_Version::use_neon_for_vector(vt->length_in_bytes());
|
// predicated instructions for better performance.
|
||||||
|
return !VM_Version::use_neon_for_vector(length_in_bytes);
|
||||||
case Op_MinReductionV:
|
case Op_MinReductionV:
|
||||||
case Op_MaxReductionV:
|
case Op_MaxReductionV:
|
||||||
// For BYTE/SHORT/INT/FLOAT/DOUBLE types, we may prefer using NEON
|
// For BYTE/SHORT/INT/FLOAT/DOUBLE types, we prefer using NEON
|
||||||
// instructions rather than SVE partial operations.
|
// instructions rather than SVE predicated instructions for
|
||||||
|
// better performance.
|
||||||
return vt->element_basic_type() == T_LONG ||
|
return vt->element_basic_type() == T_LONG ||
|
||||||
!VM_Version::use_neon_for_vector(vt->length_in_bytes());
|
!VM_Version::use_neon_for_vector(length_in_bytes);
|
||||||
default:
|
default:
|
||||||
// For other ops whose vector size is smaller than the max vector size, a
|
// For other ops whose vector size is smaller than the max vector
|
||||||
// full-sized unpredicated operation does not impact the final vector result.
|
// size, a full-sized unpredicated operation does not impact the
|
||||||
|
// vector result.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,161 +0,0 @@
|
|||||||
dnl Copyright (c) 2016, 2021, Red Hat Inc. All rights reserved.
|
|
||||||
dnl DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
dnl
|
|
||||||
dnl This code is free software; you can redistribute it and/or modify it
|
|
||||||
dnl under the terms of the GNU General Public License version 2 only, as
|
|
||||||
dnl published by the Free Software Foundation.
|
|
||||||
dnl
|
|
||||||
dnl This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
dnl version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
dnl accompanied this code).
|
|
||||||
dnl
|
|
||||||
dnl You should have received a copy of the GNU General Public License version
|
|
||||||
dnl 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
dnl Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
dnl
|
|
||||||
dnl Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
dnl or visit www.oracle.com if you need additional information or have any
|
|
||||||
dnl questions.
|
|
||||||
dnl
|
|
||||||
dnl
|
|
||||||
dnl Process this file with m4 cas.m4 to generate the CAE and wCAS
|
|
||||||
dnl instructions used in aarch64.ad.
|
|
||||||
dnl
|
|
||||||
|
|
||||||
// BEGIN This section of the file is automatically generated. Do not edit --------------
|
|
||||||
|
|
||||||
// Sundry CAS operations. Note that release is always true,
|
|
||||||
// regardless of the memory ordering of the CAS. This is because we
|
|
||||||
// need the volatile case to be sequentially consistent but there is
|
|
||||||
// no trailing StoreLoad barrier emitted by C2. Unfortunately we
|
|
||||||
// can't check the type of memory ordering here, so we always emit a
|
|
||||||
// STLXR.
|
|
||||||
|
|
||||||
// This section is generated from cas.m4
|
|
||||||
|
|
||||||
dnl Return Arg1 with two spaces before it. We need this because m4
|
|
||||||
dnl strips leading spaces from macro args.
|
|
||||||
define(`INDENT', ` $1')dnl
|
|
||||||
dnl
|
|
||||||
define(`CAS_INSN',
|
|
||||||
`
|
|
||||||
// This pattern is generated automatically from cas.m4.
|
|
||||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
|
||||||
instruct compareAndExchange$1$6(iReg$2NoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
|
|
||||||
ifelse($1$6,PAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));),
|
|
||||||
$1$6,NAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);),
|
|
||||||
$1,P,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
|
||||||
$1,N,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
|
||||||
$6,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),
|
|
||||||
`dnl')
|
|
||||||
match(Set res (CompareAndExchange$1 mem (Binary oldval newval)));
|
|
||||||
ifelse($6,Acq,'ins_cost(VOLATILE_REF_COST);`,'ins_cost(2 * VOLATILE_REF_COST);`)
|
|
||||||
effect(TEMP_DEF res, KILL cr);
|
|
||||||
format %{
|
|
||||||
"cmpxchg$5`'ifelse($6,Acq,_acq,) $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval"
|
|
||||||
%}
|
|
||||||
ins_encode %{
|
|
||||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
|
||||||
Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
|
|
||||||
/*weak*/ false, $res$$Register);
|
|
||||||
%}
|
|
||||||
ins_pipe(pipe_slow);
|
|
||||||
%}')dnl
|
|
||||||
define(`CAS_INSN4',
|
|
||||||
`
|
|
||||||
// This pattern is generated automatically from cas.m4.
|
|
||||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
|
||||||
instruct compareAndExchange$1$7(iReg$2NoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
|
|
||||||
ifelse($7,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),`dnl')
|
|
||||||
match(Set res (CompareAndExchange$1 mem (Binary oldval newval)));
|
|
||||||
ifelse($7,Acq,'ins_cost(VOLATILE_REF_COST);`,'ins_cost(2 * VOLATILE_REF_COST);`)
|
|
||||||
effect(TEMP_DEF res, KILL cr);
|
|
||||||
format %{
|
|
||||||
"cmpxchg$5`'ifelse($7,Acq,_acq,) $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval"
|
|
||||||
%}
|
|
||||||
ins_encode %{
|
|
||||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
|
||||||
Assembler::$4, /*acquire*/ ifelse($7,Acq,true,false), /*release*/ true,
|
|
||||||
/*weak*/ false, $res$$Register);
|
|
||||||
__ $6($res$$Register, $res$$Register);
|
|
||||||
%}
|
|
||||||
ins_pipe(pipe_slow);
|
|
||||||
%}')dnl
|
|
||||||
CAS_INSN4(B,I,byte,byte,b,sxtbw)
|
|
||||||
CAS_INSN4(S,I,short,halfword,s,sxthw)
|
|
||||||
CAS_INSN(I,I,int,word,w)
|
|
||||||
CAS_INSN(L,L,long,xword)
|
|
||||||
CAS_INSN(N,N,narrow oop,word,w)
|
|
||||||
CAS_INSN(P,P,ptr,xword)
|
|
||||||
dnl
|
|
||||||
CAS_INSN4(B,I,byte,byte,b,sxtbw,Acq)
|
|
||||||
CAS_INSN4(S,I,short,halfword,s,sxthw,Acq)
|
|
||||||
CAS_INSN(I,I,int,word,w,Acq)
|
|
||||||
CAS_INSN(L,L,long,xword,,Acq)
|
|
||||||
CAS_INSN(N,N,narrow oop,word,w,Acq)
|
|
||||||
CAS_INSN(P,P,ptr,xword,,Acq)
|
|
||||||
dnl
|
|
||||||
define(`CAS_INSN2',
|
|
||||||
`
|
|
||||||
// This pattern is generated automatically from cas.m4.
|
|
||||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
|
||||||
instruct weakCompareAndSwap$1$6(iRegINoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
|
|
||||||
ifelse($6,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),`dnl')
|
|
||||||
match(Set res (WeakCompareAndSwap$1 mem (Binary oldval newval)));
|
|
||||||
ifelse($6,Acq,'ins_cost(VOLATILE_REF_COST);`,'ins_cost(2 * VOLATILE_REF_COST);`)
|
|
||||||
effect(KILL cr);
|
|
||||||
format %{
|
|
||||||
"cmpxchg$5`'ifelse($6,Acq,_acq,) $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval"
|
|
||||||
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
|
||||||
%}
|
|
||||||
ins_encode %{
|
|
||||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
|
||||||
Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
|
|
||||||
/*weak*/ true, noreg);
|
|
||||||
__ csetw($res$$Register, Assembler::EQ);
|
|
||||||
%}
|
|
||||||
ins_pipe(pipe_slow);
|
|
||||||
%}')dnl
|
|
||||||
define(`CAS_INSN3',
|
|
||||||
`
|
|
||||||
// This pattern is generated automatically from cas.m4.
|
|
||||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
|
||||||
instruct weakCompareAndSwap$1$6(iRegINoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
|
|
||||||
ifelse($1$6,PAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));),
|
|
||||||
$1$6,NAcq,INDENT(predicate(needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == 0);),
|
|
||||||
$1,P,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
|
||||||
$1,N,INDENT(predicate(n->as_LoadStore()->barrier_data() == 0);),
|
|
||||||
$6,Acq,INDENT(predicate(needs_acquiring_load_exclusive(n));),
|
|
||||||
`dnl')
|
|
||||||
match(Set res (WeakCompareAndSwap$1 mem (Binary oldval newval)));
|
|
||||||
ifelse($6,Acq,'ins_cost(VOLATILE_REF_COST);`,'ins_cost(2 * VOLATILE_REF_COST);`)
|
|
||||||
effect(KILL cr);
|
|
||||||
format %{
|
|
||||||
"cmpxchg$5`'ifelse($6,Acq,_acq,) $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval"
|
|
||||||
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
|
||||||
%}
|
|
||||||
ins_encode %{
|
|
||||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
|
||||||
Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
|
|
||||||
/*weak*/ true, noreg);
|
|
||||||
__ csetw($res$$Register, Assembler::EQ);
|
|
||||||
%}
|
|
||||||
ins_pipe(pipe_slow);
|
|
||||||
%}')dnl
|
|
||||||
CAS_INSN2(B,I,byte,byte,b)
|
|
||||||
CAS_INSN2(S,I,short,halfword,s)
|
|
||||||
CAS_INSN3(I,I,int,word,w)
|
|
||||||
CAS_INSN3(L,L,long,xword)
|
|
||||||
CAS_INSN3(N,N,narrow oop,word,w)
|
|
||||||
CAS_INSN3(P,P,ptr,xword)
|
|
||||||
CAS_INSN2(B,I,byte,byte,b,Acq)
|
|
||||||
CAS_INSN2(S,I,short,halfword,s,Acq)
|
|
||||||
CAS_INSN3(I,I,int,word,w,Acq)
|
|
||||||
CAS_INSN3(L,L,long,xword,,Acq)
|
|
||||||
CAS_INSN3(N,N,narrow oop,word,w,Acq)
|
|
||||||
CAS_INSN3(P,P,ptr,xword,,Acq)
|
|
||||||
dnl
|
|
||||||
|
|
||||||
// END This section of the file is automatically generated. Do not edit --------------
|
|
||||||
@@ -5379,7 +5379,6 @@ void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
|
|||||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||||
assert (oop_recorder() != nullptr, "this assembler needs an OopRecorder");
|
assert (oop_recorder() != nullptr, "this assembler needs an OopRecorder");
|
||||||
int index = oop_recorder()->find_index(k);
|
int index = oop_recorder()->find_index(k);
|
||||||
assert(! Universe::heap()->is_in(k), "should not be an oop");
|
|
||||||
|
|
||||||
InstructionMark im(this);
|
InstructionMark im(this);
|
||||||
RelocationHolder rspec = metadata_Relocation::spec(index);
|
RelocationHolder rspec = metadata_Relocation::spec(index);
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void Relocation::pd_set_call_destination(address x) {
|
|||||||
} else {
|
} else {
|
||||||
MacroAssembler::pd_patch_instruction(addr(), x);
|
MacroAssembler::pd_patch_instruction(addr(), x);
|
||||||
}
|
}
|
||||||
assert(pd_call_destination(addr()) == x, "fail in reloc");
|
guarantee(pd_call_destination(addr()) == x, "fail in reloc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void trampoline_stub_Relocation::pd_fix_owner_after_move() {
|
void trampoline_stub_Relocation::pd_fix_owner_after_move() {
|
||||||
|
|||||||
@@ -2879,7 +2879,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKe (key) in little endian int array
|
||||||
//
|
//
|
||||||
address generate_aescrypt_encryptBlock() {
|
address generate_aescrypt_encryptBlock() {
|
||||||
__ align(CodeEntryAlignment);
|
__ align(CodeEntryAlignment);
|
||||||
@@ -2912,7 +2912,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKd (key) in little endian int array
|
||||||
//
|
//
|
||||||
address generate_aescrypt_decryptBlock() {
|
address generate_aescrypt_decryptBlock() {
|
||||||
assert(UseAES, "need AES cryptographic extension support");
|
assert(UseAES, "need AES cryptographic extension support");
|
||||||
@@ -2946,7 +2946,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKe (key) in little endian int array
|
||||||
// c_rarg3 - r vector byte array address
|
// c_rarg3 - r vector byte array address
|
||||||
// c_rarg4 - input length
|
// c_rarg4 - input length
|
||||||
//
|
//
|
||||||
@@ -3051,7 +3051,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKd (key) in little endian int array
|
||||||
// c_rarg3 - r vector byte array address
|
// c_rarg3 - r vector byte array address
|
||||||
// c_rarg4 - input length
|
// c_rarg4 - input length
|
||||||
//
|
//
|
||||||
@@ -3178,7 +3178,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKe (key) in little endian int array
|
||||||
// c_rarg3 - counter vector byte array address
|
// c_rarg3 - counter vector byte array address
|
||||||
// c_rarg4 - input length
|
// c_rarg4 - input length
|
||||||
// c_rarg5 - saved encryptedCounter start
|
// c_rarg5 - saved encryptedCounter start
|
||||||
|
|||||||
@@ -1063,6 +1063,10 @@ bool Matcher::is_reg2reg_move(MachNode* m) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Matcher::is_generic_vector(MachOper* opnd) {
|
bool Matcher::is_generic_vector(MachOper* opnd) {
|
||||||
ShouldNotReachHere(); // generic vector operands not supported
|
ShouldNotReachHere(); // generic vector operands not supported
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -157,6 +157,9 @@ inline D AtomicAccess::PlatformAdd<8>::add_then_fetch(D volatile* dest, I add_va
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
||||||
|
|||||||
@@ -1795,10 +1795,13 @@ uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *r
|
|||||||
return size; // Self copy, no move.
|
return size; // Self copy, no move.
|
||||||
|
|
||||||
if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) {
|
if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) {
|
||||||
|
int src_offset = ra_->reg2offset(src_lo);
|
||||||
|
int dst_offset = ra_->reg2offset(dst_lo);
|
||||||
|
DEBUG_ONLY(int algm = MIN2(RegMask::num_registers(ideal_reg()), (int)Matcher::stack_alignment_in_slots()) * VMRegImpl::stack_slot_size);
|
||||||
|
assert((src_lo_rc != rc_stack) || is_aligned(src_offset, algm), "unaligned vector spill sp offset %d (src)", src_offset);
|
||||||
|
assert((dst_lo_rc != rc_stack) || is_aligned(dst_offset, algm), "unaligned vector spill sp offset %d (dst)", dst_offset);
|
||||||
// Memory->Memory Spill.
|
// Memory->Memory Spill.
|
||||||
if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
|
if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
|
||||||
int src_offset = ra_->reg2offset(src_lo);
|
|
||||||
int dst_offset = ra_->reg2offset(dst_lo);
|
|
||||||
if (masm) {
|
if (masm) {
|
||||||
__ ld(R0, src_offset, R1_SP);
|
__ ld(R0, src_offset, R1_SP);
|
||||||
__ std(R0, dst_offset, R1_SP);
|
__ std(R0, dst_offset, R1_SP);
|
||||||
@@ -1806,26 +1809,20 @@ uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *r
|
|||||||
__ std(R0, dst_offset+8, R1_SP);
|
__ std(R0, dst_offset+8, R1_SP);
|
||||||
}
|
}
|
||||||
size += 16;
|
size += 16;
|
||||||
|
#ifndef PRODUCT
|
||||||
|
if (st != nullptr) {
|
||||||
|
st->print("%-7s [R1_SP + #%d] -> [R1_SP + #%d] \t// vector spill copy", "SPILL", src_offset, dst_offset);
|
||||||
|
}
|
||||||
|
#endif // !PRODUCT
|
||||||
}
|
}
|
||||||
// VectorRegister->Memory Spill.
|
// VectorRegister->Memory Spill.
|
||||||
else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) {
|
else if (src_lo_rc == rc_vec && dst_lo_rc == rc_stack) {
|
||||||
VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
|
VectorSRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]).to_vsr();
|
||||||
int dst_offset = ra_->reg2offset(dst_lo);
|
|
||||||
if (PowerArchitecturePPC64 >= 9) {
|
if (PowerArchitecturePPC64 >= 9) {
|
||||||
if (is_aligned(dst_offset, 16)) {
|
if (masm) {
|
||||||
if (masm) {
|
__ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16_Power9
|
||||||
__ stxv(Rsrc, dst_offset, R1_SP); // matches storeV16_Power9
|
|
||||||
}
|
|
||||||
size += 4;
|
|
||||||
} else {
|
|
||||||
// Other alignment can be used by Vector API (VectorPayload in rearrangeOp,
|
|
||||||
// observed with VectorRearrangeTest.java on Power9).
|
|
||||||
if (masm) {
|
|
||||||
__ addi(R0, R1_SP, dst_offset);
|
|
||||||
__ stxvx(Rsrc, R0); // matches storeV16_Power9 (regarding element ordering)
|
|
||||||
}
|
|
||||||
size += 8;
|
|
||||||
}
|
}
|
||||||
|
size += 4;
|
||||||
} else {
|
} else {
|
||||||
if (masm) {
|
if (masm) {
|
||||||
__ addi(R0, R1_SP, dst_offset);
|
__ addi(R0, R1_SP, dst_offset);
|
||||||
@@ -1833,24 +1830,25 @@ uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *r
|
|||||||
}
|
}
|
||||||
size += 8;
|
size += 8;
|
||||||
}
|
}
|
||||||
|
#ifndef PRODUCT
|
||||||
|
if (st != nullptr) {
|
||||||
|
if (PowerArchitecturePPC64 >= 9) {
|
||||||
|
st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "STXV", Matcher::regName[src_lo], dst_offset);
|
||||||
|
} else {
|
||||||
|
st->print("%-7s R0, R1_SP, %d \t// vector spill copy\n\t"
|
||||||
|
"%-7s %s, [R0] \t// vector spill copy", "ADDI", dst_offset, "STXVD2X", Matcher::regName[src_lo]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // !PRODUCT
|
||||||
}
|
}
|
||||||
// Memory->VectorRegister Spill.
|
// Memory->VectorRegister Spill.
|
||||||
else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) {
|
else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vec) {
|
||||||
VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
|
VectorSRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]).to_vsr();
|
||||||
int src_offset = ra_->reg2offset(src_lo);
|
|
||||||
if (PowerArchitecturePPC64 >= 9) {
|
if (PowerArchitecturePPC64 >= 9) {
|
||||||
if (is_aligned(src_offset, 16)) {
|
if (masm) {
|
||||||
if (masm) {
|
__ lxv(Rdst, src_offset, R1_SP);
|
||||||
__ lxv(Rdst, src_offset, R1_SP);
|
|
||||||
}
|
|
||||||
size += 4;
|
|
||||||
} else {
|
|
||||||
if (masm) {
|
|
||||||
__ addi(R0, R1_SP, src_offset);
|
|
||||||
__ lxvx(Rdst, R0);
|
|
||||||
}
|
|
||||||
size += 8;
|
|
||||||
}
|
}
|
||||||
|
size += 4;
|
||||||
} else {
|
} else {
|
||||||
if (masm) {
|
if (masm) {
|
||||||
__ addi(R0, R1_SP, src_offset);
|
__ addi(R0, R1_SP, src_offset);
|
||||||
@@ -1858,6 +1856,16 @@ uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *r
|
|||||||
}
|
}
|
||||||
size += 8;
|
size += 8;
|
||||||
}
|
}
|
||||||
|
#ifndef PRODUCT
|
||||||
|
if (st != nullptr) {
|
||||||
|
if (PowerArchitecturePPC64 >= 9) {
|
||||||
|
st->print("%-7s %s, [R1_SP + #%d] \t// vector spill copy", "LXV", Matcher::regName[dst_lo], src_offset);
|
||||||
|
} else {
|
||||||
|
st->print("%-7s R0, R1_SP, %d \t// vector spill copy\n\t"
|
||||||
|
"%-7s %s, [R0] \t// vector spill copy", "ADDI", src_offset, "LXVD2X", Matcher::regName[dst_lo]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // !PRODUCT
|
||||||
}
|
}
|
||||||
// VectorRegister->VectorRegister.
|
// VectorRegister->VectorRegister.
|
||||||
else if (src_lo_rc == rc_vec && dst_lo_rc == rc_vec) {
|
else if (src_lo_rc == rc_vec && dst_lo_rc == rc_vec) {
|
||||||
@@ -1867,6 +1875,12 @@ uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *r
|
|||||||
__ xxlor(Rdst, Rsrc, Rsrc);
|
__ xxlor(Rdst, Rsrc, Rsrc);
|
||||||
}
|
}
|
||||||
size += 4;
|
size += 4;
|
||||||
|
#ifndef PRODUCT
|
||||||
|
if (st != nullptr) {
|
||||||
|
st->print("%-7s %s, %s, %s\t// vector spill copy",
|
||||||
|
"XXLOR", Matcher::regName[dst_lo], Matcher::regName[src_lo], Matcher::regName[src_lo]);
|
||||||
|
}
|
||||||
|
#endif // !PRODUCT
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ShouldNotReachHere(); // No VR spill.
|
ShouldNotReachHere(); // No VR spill.
|
||||||
@@ -2383,6 +2397,10 @@ bool Matcher::is_reg2reg_move(MachNode* m) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Matcher::is_generic_vector(MachOper* opnd) {
|
bool Matcher::is_generic_vector(MachOper* opnd) {
|
||||||
ShouldNotReachHere(); // generic vector operands not supported
|
ShouldNotReachHere(); // generic vector operands not supported
|
||||||
return false;
|
return false;
|
||||||
@@ -6317,8 +6335,36 @@ instruct loadConD_Ex(regD dst, immD src) %{
|
|||||||
// Prefetch instructions.
|
// Prefetch instructions.
|
||||||
// Must be safe to execute with invalid address (cannot fault).
|
// Must be safe to execute with invalid address (cannot fault).
|
||||||
|
|
||||||
|
// Special prefetch versions which use the dcbz instruction.
|
||||||
|
instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{
|
||||||
|
match(PrefetchAllocation (AddP mem src));
|
||||||
|
predicate(AllocatePrefetchStyle == 3);
|
||||||
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
|
format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %}
|
||||||
|
size(4);
|
||||||
|
ins_encode %{
|
||||||
|
__ dcbz($src$$Register, $mem$$base$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_memory);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{
|
||||||
|
match(PrefetchAllocation mem);
|
||||||
|
predicate(AllocatePrefetchStyle == 3);
|
||||||
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
|
format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %}
|
||||||
|
size(4);
|
||||||
|
ins_encode %{
|
||||||
|
__ dcbz($mem$$base$$Register);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_memory);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
|
instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
|
||||||
match(PrefetchAllocation (AddP mem src));
|
match(PrefetchAllocation (AddP mem src));
|
||||||
|
predicate(AllocatePrefetchStyle != 3);
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
|
format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
|
||||||
@@ -6331,6 +6377,7 @@ instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
|
|||||||
|
|
||||||
instruct prefetch_alloc_no_offset(indirectMemory mem) %{
|
instruct prefetch_alloc_no_offset(indirectMemory mem) %{
|
||||||
match(PrefetchAllocation mem);
|
match(PrefetchAllocation mem);
|
||||||
|
predicate(AllocatePrefetchStyle != 3);
|
||||||
ins_cost(MEMORY_REF_COST);
|
ins_cost(MEMORY_REF_COST);
|
||||||
|
|
||||||
format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
|
format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
|
||||||
|
|||||||
@@ -2956,7 +2956,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// Arguments for generated stub:
|
// Arguments for generated stub:
|
||||||
// R3_ARG1 - source byte array address
|
// R3_ARG1 - source byte array address
|
||||||
// R4_ARG2 - destination byte array address
|
// R4_ARG2 - destination byte array address
|
||||||
// R5_ARG3 - K (key) in little endian int array
|
// R5_ARG3 - sessionKe (key) in little endian int array
|
||||||
address generate_aescrypt_decryptBlock() {
|
address generate_aescrypt_decryptBlock() {
|
||||||
assert(UseAES, "need AES instructions and misaligned SSE support");
|
assert(UseAES, "need AES instructions and misaligned SSE support");
|
||||||
StubId stub_id = StubId::stubgen_aescrypt_decryptBlock_id;
|
StubId stub_id = StubId::stubgen_aescrypt_decryptBlock_id;
|
||||||
|
|||||||
@@ -2067,6 +2067,83 @@ void C2_MacroAssembler::enc_cmove_cmp_fp(int cmpFlag, FloatRegister op1, FloatRe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void C2_MacroAssembler::enc_cmove_fp_cmp(int cmpFlag, Register op1, Register op2,
|
||||||
|
FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
bool is_unsigned = (cmpFlag & unsigned_branch_mask) == unsigned_branch_mask;
|
||||||
|
int op_select = cmpFlag & (~unsigned_branch_mask);
|
||||||
|
|
||||||
|
switch (op_select) {
|
||||||
|
case BoolTest::eq:
|
||||||
|
cmov_fp_eq(op1, op2, dst, src, is_single);
|
||||||
|
break;
|
||||||
|
case BoolTest::ne:
|
||||||
|
cmov_fp_ne(op1, op2, dst, src, is_single);
|
||||||
|
break;
|
||||||
|
case BoolTest::le:
|
||||||
|
if (is_unsigned) {
|
||||||
|
cmov_fp_leu(op1, op2, dst, src, is_single);
|
||||||
|
} else {
|
||||||
|
cmov_fp_le(op1, op2, dst, src, is_single);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BoolTest::ge:
|
||||||
|
if (is_unsigned) {
|
||||||
|
cmov_fp_geu(op1, op2, dst, src, is_single);
|
||||||
|
} else {
|
||||||
|
cmov_fp_ge(op1, op2, dst, src, is_single);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BoolTest::lt:
|
||||||
|
if (is_unsigned) {
|
||||||
|
cmov_fp_ltu(op1, op2, dst, src, is_single);
|
||||||
|
} else {
|
||||||
|
cmov_fp_lt(op1, op2, dst, src, is_single);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BoolTest::gt:
|
||||||
|
if (is_unsigned) {
|
||||||
|
cmov_fp_gtu(op1, op2, dst, src, is_single);
|
||||||
|
} else {
|
||||||
|
cmov_fp_gt(op1, op2, dst, src, is_single);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false, "unsupported compare condition");
|
||||||
|
ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C2_MacroAssembler::enc_cmove_fp_cmp_fp(int cmpFlag,
|
||||||
|
FloatRegister op1, FloatRegister op2,
|
||||||
|
FloatRegister dst, FloatRegister src,
|
||||||
|
bool cmp_single, bool cmov_single) {
|
||||||
|
int op_select = cmpFlag & (~unsigned_branch_mask);
|
||||||
|
|
||||||
|
switch (op_select) {
|
||||||
|
case BoolTest::eq:
|
||||||
|
cmov_fp_cmp_fp_eq(op1, op2, dst, src, cmp_single, cmov_single);
|
||||||
|
break;
|
||||||
|
case BoolTest::ne:
|
||||||
|
cmov_fp_cmp_fp_ne(op1, op2, dst, src, cmp_single, cmov_single);
|
||||||
|
break;
|
||||||
|
case BoolTest::le:
|
||||||
|
cmov_fp_cmp_fp_le(op1, op2, dst, src, cmp_single, cmov_single);
|
||||||
|
break;
|
||||||
|
case BoolTest::ge:
|
||||||
|
cmov_fp_cmp_fp_ge(op1, op2, dst, src, cmp_single, cmov_single);
|
||||||
|
break;
|
||||||
|
case BoolTest::lt:
|
||||||
|
cmov_fp_cmp_fp_lt(op1, op2, dst, src, cmp_single, cmov_single);
|
||||||
|
break;
|
||||||
|
case BoolTest::gt:
|
||||||
|
cmov_fp_cmp_fp_gt(op1, op2, dst, src, cmp_single, cmov_single);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false, "unsupported compare condition");
|
||||||
|
ShouldNotReachHere();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set dst to NaN if any NaN input.
|
// Set dst to NaN if any NaN input.
|
||||||
void C2_MacroAssembler::minmax_fp(FloatRegister dst, FloatRegister src1, FloatRegister src2,
|
void C2_MacroAssembler::minmax_fp(FloatRegister dst, FloatRegister src1, FloatRegister src2,
|
||||||
FLOAT_TYPE ft, bool is_min) {
|
FLOAT_TYPE ft, bool is_min) {
|
||||||
|
|||||||
@@ -132,6 +132,13 @@
|
|||||||
FloatRegister op1, FloatRegister op2,
|
FloatRegister op1, FloatRegister op2,
|
||||||
Register dst, Register src, bool is_single);
|
Register dst, Register src, bool is_single);
|
||||||
|
|
||||||
|
void enc_cmove_fp_cmp(int cmpFlag, Register op1, Register op2,
|
||||||
|
FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
|
||||||
|
void enc_cmove_fp_cmp_fp(int cmpFlag, FloatRegister op1, FloatRegister op2,
|
||||||
|
FloatRegister dst, FloatRegister src,
|
||||||
|
bool cmp_single, bool cmov_single);
|
||||||
|
|
||||||
void spill(Register r, bool is64, int offset) {
|
void spill(Register r, bool is64, int offset) {
|
||||||
is64 ? sd(r, Address(sp, offset))
|
is64 ? sd(r, Address(sp, offset))
|
||||||
: sw(r, Address(sp, offset));
|
: sw(r, Address(sp, offset));
|
||||||
|
|||||||
@@ -1233,7 +1233,119 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist
|
|||||||
bind(no_set);
|
bind(no_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------- cmove, compare float -----------
|
// ----------- cmove float/double -----------
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_eq(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
bne(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_ne(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
beq(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_le(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
bgt(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_leu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
bgtu(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_ge(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
blt(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_geu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
bltu(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_lt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
bge(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_ltu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
bgeu(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_gt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
ble(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_gtu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
|
||||||
|
Label no_set;
|
||||||
|
bleu(cmp1, cmp2, no_set);
|
||||||
|
if (is_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------- cmove, compare float/double -----------
|
||||||
//
|
//
|
||||||
// For CmpF/D + CMoveI/L, ordered ones are quite straight and simple,
|
// For CmpF/D + CMoveI/L, ordered ones are quite straight and simple,
|
||||||
// so, just list behaviour of unordered ones as follow.
|
// so, just list behaviour of unordered ones as follow.
|
||||||
@@ -1391,6 +1503,148 @@ void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Regi
|
|||||||
bind(no_set);
|
bind(no_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------- cmove float/double, compare float/double -----------
|
||||||
|
|
||||||
|
// Move src to dst only if cmp1 == cmp2,
|
||||||
|
// otherwise leave dst unchanged, including the case where one of them is NaN.
|
||||||
|
// Clarification:
|
||||||
|
// java code : cmp1 != cmp2 ? dst : src
|
||||||
|
// transformed to : CMove dst, (cmp1 eq cmp2), dst, src
|
||||||
|
void MacroAssembler::cmov_fp_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2,
|
||||||
|
FloatRegister dst, FloatRegister src,
|
||||||
|
bool cmp_single, bool cmov_single) {
|
||||||
|
Label no_set;
|
||||||
|
if (cmp_single) {
|
||||||
|
// jump if cmp1 != cmp2, including the case of NaN
|
||||||
|
// not jump (i.e. move src to dst) if cmp1 == cmp2
|
||||||
|
float_bne(cmp1, cmp2, no_set);
|
||||||
|
} else {
|
||||||
|
double_bne(cmp1, cmp2, no_set);
|
||||||
|
}
|
||||||
|
if (cmov_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep dst unchanged only if cmp1 == cmp2,
|
||||||
|
// otherwise move src to dst, including the case where one of them is NaN.
|
||||||
|
// Clarification:
|
||||||
|
// java code : cmp1 == cmp2 ? dst : src
|
||||||
|
// transformed to : CMove dst, (cmp1 ne cmp2), dst, src
|
||||||
|
void MacroAssembler::cmov_fp_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2,
|
||||||
|
FloatRegister dst, FloatRegister src,
|
||||||
|
bool cmp_single, bool cmov_single) {
|
||||||
|
Label no_set;
|
||||||
|
if (cmp_single) {
|
||||||
|
// jump if cmp1 == cmp2
|
||||||
|
// not jump (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
|
||||||
|
float_beq(cmp1, cmp2, no_set);
|
||||||
|
} else {
|
||||||
|
double_beq(cmp1, cmp2, no_set);
|
||||||
|
}
|
||||||
|
if (cmov_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When cmp1 <= cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
|
||||||
|
// Clarification
|
||||||
|
// scenario 1:
|
||||||
|
// java code : cmp2 < cmp1 ? dst : src
|
||||||
|
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
|
||||||
|
// scenario 2:
|
||||||
|
// java code : cmp1 > cmp2 ? dst : src
|
||||||
|
// transformed to : CMove dst, (cmp1 le cmp2), dst, src
|
||||||
|
void MacroAssembler::cmov_fp_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2,
|
||||||
|
FloatRegister dst, FloatRegister src,
|
||||||
|
bool cmp_single, bool cmov_single) {
|
||||||
|
Label no_set;
|
||||||
|
if (cmp_single) {
|
||||||
|
// jump if cmp1 > cmp2
|
||||||
|
// not jump (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
|
||||||
|
float_bgt(cmp1, cmp2, no_set);
|
||||||
|
} else {
|
||||||
|
double_bgt(cmp1, cmp2, no_set);
|
||||||
|
}
|
||||||
|
if (cmov_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2,
|
||||||
|
FloatRegister dst, FloatRegister src,
|
||||||
|
bool cmp_single, bool cmov_single) {
|
||||||
|
Label no_set;
|
||||||
|
if (cmp_single) {
|
||||||
|
// jump if cmp1 < cmp2 or either is NaN
|
||||||
|
// not jump (i.e. move src to dst) if cmp1 >= cmp2
|
||||||
|
float_blt(cmp1, cmp2, no_set, false, true);
|
||||||
|
} else {
|
||||||
|
double_blt(cmp1, cmp2, no_set, false, true);
|
||||||
|
}
|
||||||
|
if (cmov_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When cmp1 < cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
|
||||||
|
// Clarification
|
||||||
|
// scenario 1:
|
||||||
|
// java code : cmp2 <= cmp1 ? dst : src
|
||||||
|
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
|
||||||
|
// scenario 2:
|
||||||
|
// java code : cmp1 >= cmp2 ? dst : src
|
||||||
|
// transformed to : CMove dst, (cmp1 lt cmp2), dst, src
|
||||||
|
void MacroAssembler::cmov_fp_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2,
|
||||||
|
FloatRegister dst, FloatRegister src,
|
||||||
|
bool cmp_single, bool cmov_single) {
|
||||||
|
Label no_set;
|
||||||
|
if (cmp_single) {
|
||||||
|
// jump if cmp1 >= cmp2
|
||||||
|
// not jump (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
|
||||||
|
float_bge(cmp1, cmp2, no_set);
|
||||||
|
} else {
|
||||||
|
double_bge(cmp1, cmp2, no_set);
|
||||||
|
}
|
||||||
|
if (cmov_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::cmov_fp_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2,
|
||||||
|
FloatRegister dst, FloatRegister src,
|
||||||
|
bool cmp_single, bool cmov_single) {
|
||||||
|
Label no_set;
|
||||||
|
if (cmp_single) {
|
||||||
|
// jump if cmp1 <= cmp2 or either is NaN
|
||||||
|
// not jump (i.e. move src to dst) if cmp1 > cmp2
|
||||||
|
float_ble(cmp1, cmp2, no_set, false, true);
|
||||||
|
} else {
|
||||||
|
double_ble(cmp1, cmp2, no_set, false, true);
|
||||||
|
}
|
||||||
|
if (cmov_single) {
|
||||||
|
fmv_s(dst, src);
|
||||||
|
} else {
|
||||||
|
fmv_d(dst, src);
|
||||||
|
}
|
||||||
|
bind(no_set);
|
||||||
|
}
|
||||||
|
|
||||||
// Float compare branch instructions
|
// Float compare branch instructions
|
||||||
|
|
||||||
#define INSN(NAME, FLOATCMP, BRANCH) \
|
#define INSN(NAME, FLOATCMP, BRANCH) \
|
||||||
@@ -4933,7 +5187,6 @@ void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
|
|||||||
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
assert (UseCompressedClassPointers, "should only be used for compressed headers");
|
||||||
assert (oop_recorder() != nullptr, "this assembler needs an OopRecorder");
|
assert (oop_recorder() != nullptr, "this assembler needs an OopRecorder");
|
||||||
int index = oop_recorder()->find_index(k);
|
int index = oop_recorder()->find_index(k);
|
||||||
assert(!Universe::heap()->is_in(k), "should not be an oop");
|
|
||||||
|
|
||||||
narrowKlass nk = CompressedKlassPointers::encode(k);
|
narrowKlass nk = CompressedKlassPointers::encode(k);
|
||||||
relocate(metadata_Relocation::spec(index), [&] {
|
relocate(metadata_Relocation::spec(index), [&] {
|
||||||
|
|||||||
@@ -665,6 +665,24 @@ class MacroAssembler: public Assembler {
|
|||||||
void cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
|
void cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
|
||||||
void cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
|
void cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single);
|
||||||
|
|
||||||
|
void cmov_fp_eq(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
void cmov_fp_ne(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
void cmov_fp_le(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
void cmov_fp_leu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
void cmov_fp_ge(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
void cmov_fp_geu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
void cmov_fp_lt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
void cmov_fp_ltu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
void cmov_fp_gt(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
void cmov_fp_gtu(Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single);
|
||||||
|
|
||||||
|
void cmov_fp_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||||
|
void cmov_fp_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||||
|
void cmov_fp_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||||
|
void cmov_fp_cmp_fp_ge(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||||
|
void cmov_fp_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||||
|
void cmov_fp_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, FloatRegister dst, FloatRegister src, bool cmp_single, bool cmov_single);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// We try to follow risc-v asm menomics.
|
// We try to follow risc-v asm menomics.
|
||||||
// But as we don't layout a reachable GOT,
|
// But as we don't layout a reachable GOT,
|
||||||
|
|||||||
@@ -1924,8 +1924,6 @@ bool Matcher::match_rule_supported(int opcode) {
|
|||||||
case Op_SubHF:
|
case Op_SubHF:
|
||||||
return UseZfh;
|
return UseZfh;
|
||||||
|
|
||||||
case Op_CMoveF:
|
|
||||||
case Op_CMoveD:
|
|
||||||
case Op_CMoveP:
|
case Op_CMoveP:
|
||||||
case Op_CMoveN:
|
case Op_CMoveN:
|
||||||
return false;
|
return false;
|
||||||
@@ -2053,6 +2051,10 @@ bool Matcher::is_reg2reg_move(MachNode* m) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Matcher::is_generic_vector(MachOper* opnd) {
|
bool Matcher::is_generic_vector(MachOper* opnd) {
|
||||||
ShouldNotReachHere(); // generic vector operands not supported
|
ShouldNotReachHere(); // generic vector operands not supported
|
||||||
return false;
|
return false;
|
||||||
@@ -10462,6 +10464,286 @@ instruct cmovL_cmpP(iRegLNoSp dst, iRegL src, iRegP op1, iRegP op2, cmpOpU cop)
|
|||||||
ins_pipe(pipe_class_compare);
|
ins_pipe(pipe_class_compare);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
// --------- CMoveF ---------
|
||||||
|
|
||||||
|
instruct cmovF_cmpI(fRegF dst, fRegF src, iRegI op1, iRegI op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveF (Binary cop (CmpI op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpI\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovF_cmpU(fRegF dst, fRegF src, iRegI op1, iRegI op2, cmpOpU cop) %{
|
||||||
|
match(Set dst (CMoveF (Binary cop (CmpU op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpU\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovF_cmpL(fRegF dst, fRegF src, iRegL op1, iRegL op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveF (Binary cop (CmpL op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpL\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovF_cmpUL(fRegF dst, fRegF src, iRegL op1, iRegL op2, cmpOpU cop) %{
|
||||||
|
match(Set dst (CMoveF (Binary cop (CmpUL op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpUL\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovF_cmpF(fRegF dst, fRegF src, fRegF op1, fRegF op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveF (Binary cop (CmpF op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpF\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp_fp($cop$$cmpcode,
|
||||||
|
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||||
|
true /* cmp_single */, true /* cmov_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovF_cmpD(fRegF dst, fRegF src, fRegD op1, fRegD op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveF (Binary cop (CmpD op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpD\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
|
||||||
|
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||||
|
false /* cmp_single */, true /* cmov_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovF_cmpN(fRegF dst, fRegF src, iRegN op1, iRegN op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveF (Binary cop (CmpN op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpN\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovF_cmpP(fRegF dst, fRegF src, iRegP op1, iRegP op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveF (Binary cop (CmpP op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveF $dst, ($op1 $cop $op2), $dst, $src\t#@cmovF_cmpP\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), true /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
// --------- CMoveD ---------
|
||||||
|
|
||||||
|
instruct cmovD_cmpI(fRegD dst, fRegD src, iRegI op1, iRegI op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveD (Binary cop (CmpI op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpI\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovD_cmpU(fRegD dst, fRegD src, iRegI op1, iRegI op2, cmpOpU cop) %{
|
||||||
|
match(Set dst (CMoveD (Binary cop (CmpU op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpU\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovD_cmpL(fRegD dst, fRegD src, iRegL op1, iRegL op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveD (Binary cop (CmpL op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpL\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovD_cmpUL(fRegD dst, fRegD src, iRegL op1, iRegL op2, cmpOpU cop) %{
|
||||||
|
match(Set dst (CMoveD (Binary cop (CmpUL op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpUL\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovD_cmpF(fRegD dst, fRegD src, fRegF op1, fRegF op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveD (Binary cop (CmpF op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpF\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp_fp($cop$$cmpcode,
|
||||||
|
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||||
|
true /* cmp_single */, false /* cmov_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovD_cmpD(fRegD dst, fRegD src, fRegD op1, fRegD op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveD (Binary cop (CmpD op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpD\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp_fp($cop$$cmpcode | C2_MacroAssembler::double_branch_mask,
|
||||||
|
as_FloatRegister($op1$$reg), as_FloatRegister($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||||
|
false /* cmp_single */, false /* cmov_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovD_cmpN(fRegD dst, fRegD src, iRegN op1, iRegN op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveD (Binary cop (CmpN op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpN\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct cmovD_cmpP(fRegD dst, fRegD src, iRegP op1, iRegP op2, cmpOp cop) %{
|
||||||
|
match(Set dst (CMoveD (Binary cop (CmpP op1 op2)) (Binary dst src)));
|
||||||
|
ins_cost(ALU_COST + BRANCH_COST);
|
||||||
|
|
||||||
|
format %{
|
||||||
|
"CMoveD $dst, ($op1 $cop $op2), $dst, $src\t#@cmovD_cmpP\n\t"
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ enc_cmove_fp_cmp($cop$$cmpcode | C2_MacroAssembler::unsigned_branch_mask,
|
||||||
|
as_Register($op1$$reg), as_Register($op2$$reg),
|
||||||
|
as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), false /* is_single */);
|
||||||
|
%}
|
||||||
|
|
||||||
|
ins_pipe(pipe_class_compare);
|
||||||
|
%}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Procedure Call/Return Instructions
|
// Procedure Call/Return Instructions
|
||||||
|
|
||||||
|
|||||||
@@ -2463,7 +2463,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKe (key) in little endian int array
|
||||||
//
|
//
|
||||||
address generate_aescrypt_encryptBlock() {
|
address generate_aescrypt_encryptBlock() {
|
||||||
assert(UseAESIntrinsics, "need AES instructions (Zvkned extension) support");
|
assert(UseAESIntrinsics, "need AES instructions (Zvkned extension) support");
|
||||||
@@ -2493,8 +2493,8 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
__ vsetivli(x0, 4, Assembler::e32, Assembler::m1);
|
__ vsetivli(x0, 4, Assembler::e32, Assembler::m1);
|
||||||
__ vle32_v(res, from);
|
__ vle32_v(res, from);
|
||||||
|
|
||||||
__ mv(t2, 52);
|
__ mv(t2, 52); // key length could be only {11, 13, 15} * 4 = {44, 52, 60}
|
||||||
__ blt(keylen, t2, L_aes128);
|
__ bltu(keylen, t2, L_aes128);
|
||||||
__ beq(keylen, t2, L_aes192);
|
__ beq(keylen, t2, L_aes192);
|
||||||
// Else we fallthrough to the biggest case (256-bit key size)
|
// Else we fallthrough to the biggest case (256-bit key size)
|
||||||
|
|
||||||
@@ -2542,7 +2542,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKe (key) in little endian int array
|
||||||
//
|
//
|
||||||
address generate_aescrypt_decryptBlock() {
|
address generate_aescrypt_decryptBlock() {
|
||||||
assert(UseAESIntrinsics, "need AES instructions (Zvkned extension) support");
|
assert(UseAESIntrinsics, "need AES instructions (Zvkned extension) support");
|
||||||
@@ -2572,8 +2572,8 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
__ vsetivli(x0, 4, Assembler::e32, Assembler::m1);
|
__ vsetivli(x0, 4, Assembler::e32, Assembler::m1);
|
||||||
__ vle32_v(res, from);
|
__ vle32_v(res, from);
|
||||||
|
|
||||||
__ mv(t2, 52);
|
__ mv(t2, 52); // key length could be only {11, 13, 15} * 4 = {44, 52, 60}
|
||||||
__ blt(keylen, t2, L_aes128);
|
__ bltu(keylen, t2, L_aes128);
|
||||||
__ beq(keylen, t2, L_aes192);
|
__ beq(keylen, t2, L_aes192);
|
||||||
// Else we fallthrough to the biggest case (256-bit key size)
|
// Else we fallthrough to the biggest case (256-bit key size)
|
||||||
|
|
||||||
@@ -2606,6 +2606,401 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cipherBlockChaining_encryptAESCrypt(int round, Register from, Register to, Register key,
|
||||||
|
Register rvec, Register input_len) {
|
||||||
|
const Register len = x29;
|
||||||
|
|
||||||
|
VectorRegister working_vregs[] = {
|
||||||
|
v1, v2, v3, v4, v5, v6, v7, v8,
|
||||||
|
v9, v10, v11, v12, v13, v14, v15
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned int BLOCK_SIZE = 16;
|
||||||
|
|
||||||
|
__ mv(len, input_len);
|
||||||
|
// load init rvec
|
||||||
|
__ vsetivli(x0, 4, Assembler::e32, Assembler::m1);
|
||||||
|
__ vle32_v(v16, rvec);
|
||||||
|
|
||||||
|
generate_aes_loadkeys(key, working_vregs, round);
|
||||||
|
Label L_enc_loop;
|
||||||
|
__ bind(L_enc_loop);
|
||||||
|
// Encrypt from source by block size
|
||||||
|
__ vle32_v(v17, from);
|
||||||
|
__ addi(from, from, BLOCK_SIZE);
|
||||||
|
__ vxor_vv(v16, v16, v17);
|
||||||
|
generate_aes_encrypt(v16, working_vregs, round);
|
||||||
|
__ vse32_v(v16, to);
|
||||||
|
__ addi(to, to, BLOCK_SIZE);
|
||||||
|
__ subi(len, len, BLOCK_SIZE);
|
||||||
|
__ bnez(len, L_enc_loop);
|
||||||
|
|
||||||
|
// save current rvec and return
|
||||||
|
__ vse32_v(v16, rvec);
|
||||||
|
__ mv(x10, input_len);
|
||||||
|
__ leave();
|
||||||
|
__ ret();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arguments:
|
||||||
|
//
|
||||||
|
// Inputs:
|
||||||
|
// c_rarg0 - source byte array address
|
||||||
|
// c_rarg1 - destination byte array address
|
||||||
|
// c_rarg2 - K (key) in little endian int array
|
||||||
|
// c_rarg3 - r vector byte array address
|
||||||
|
// c_rarg4 - input length
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// x10 - input length
|
||||||
|
//
|
||||||
|
address generate_cipherBlockChaining_encryptAESCrypt() {
|
||||||
|
assert(UseAESIntrinsics, "Must be");
|
||||||
|
assert(UseZvkn, "need AES instructions (Zvkned extension) support");
|
||||||
|
__ align(CodeEntryAlignment);
|
||||||
|
StubId stub_id = StubId::stubgen_cipherBlockChaining_encryptAESCrypt_id;
|
||||||
|
StubCodeMark mark(this, stub_id);
|
||||||
|
|
||||||
|
const Register from = c_rarg0;
|
||||||
|
const Register to = c_rarg1;
|
||||||
|
const Register key = c_rarg2;
|
||||||
|
const Register rvec = c_rarg3;
|
||||||
|
const Register input_len = c_rarg4;
|
||||||
|
|
||||||
|
const Register keylen = x28;
|
||||||
|
|
||||||
|
address start = __ pc();
|
||||||
|
__ enter();
|
||||||
|
|
||||||
|
Label L_aes128, L_aes192;
|
||||||
|
// Compute #rounds for AES based on the length of the key array
|
||||||
|
__ lwu(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
|
||||||
|
__ mv(t0, 52);
|
||||||
|
__ bltu(keylen, t0, L_aes128);
|
||||||
|
__ beq(keylen, t0, L_aes192);
|
||||||
|
// Else we fallthrough to the biggest case (256-bit key size)
|
||||||
|
|
||||||
|
// Note: the following function performs key += 15*16
|
||||||
|
cipherBlockChaining_encryptAESCrypt(15, from, to, key, rvec, input_len);
|
||||||
|
|
||||||
|
// Note: the following function performs key += 11*16
|
||||||
|
__ bind(L_aes128);
|
||||||
|
cipherBlockChaining_encryptAESCrypt(11, from, to, key, rvec, input_len);
|
||||||
|
|
||||||
|
// Note: the following function performs key += 13*16
|
||||||
|
__ bind(L_aes192);
|
||||||
|
cipherBlockChaining_encryptAESCrypt(13, from, to, key, rvec, input_len);
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cipherBlockChaining_decryptAESCrypt(int round, Register from, Register to, Register key,
|
||||||
|
Register rvec, Register input_len) {
|
||||||
|
const Register len = x29;
|
||||||
|
|
||||||
|
VectorRegister working_vregs[] = {
|
||||||
|
v1, v2, v3, v4, v5, v6, v7, v8,
|
||||||
|
v9, v10, v11, v12, v13, v14, v15
|
||||||
|
};
|
||||||
|
|
||||||
|
const unsigned int BLOCK_SIZE = 16;
|
||||||
|
|
||||||
|
__ mv(len, input_len);
|
||||||
|
// load init rvec
|
||||||
|
__ vsetivli(x0, 4, Assembler::e32, Assembler::m1);
|
||||||
|
__ vle32_v(v16, rvec);
|
||||||
|
|
||||||
|
generate_aes_loadkeys(key, working_vregs, round);
|
||||||
|
Label L_dec_loop;
|
||||||
|
// Decrypt from source by block size
|
||||||
|
__ bind(L_dec_loop);
|
||||||
|
__ vle32_v(v17, from);
|
||||||
|
__ addi(from, from, BLOCK_SIZE);
|
||||||
|
__ vmv_v_v(v18, v17);
|
||||||
|
generate_aes_decrypt(v17, working_vregs, round);
|
||||||
|
__ vxor_vv(v17, v17, v16);
|
||||||
|
__ vse32_v(v17, to);
|
||||||
|
__ vmv_v_v(v16, v18);
|
||||||
|
__ addi(to, to, BLOCK_SIZE);
|
||||||
|
__ subi(len, len, BLOCK_SIZE);
|
||||||
|
__ bnez(len, L_dec_loop);
|
||||||
|
|
||||||
|
// save current rvec and return
|
||||||
|
__ vse32_v(v16, rvec);
|
||||||
|
__ mv(x10, input_len);
|
||||||
|
__ leave();
|
||||||
|
__ ret();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arguments:
|
||||||
|
//
|
||||||
|
// Inputs:
|
||||||
|
// c_rarg0 - source byte array address
|
||||||
|
// c_rarg1 - destination byte array address
|
||||||
|
// c_rarg2 - K (key) in little endian int array
|
||||||
|
// c_rarg3 - r vector byte array address
|
||||||
|
// c_rarg4 - input length
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// x10 - input length
|
||||||
|
//
|
||||||
|
address generate_cipherBlockChaining_decryptAESCrypt() {
|
||||||
|
assert(UseAESIntrinsics, "Must be");
|
||||||
|
assert(UseZvkn, "need AES instructions (Zvkned extension) support");
|
||||||
|
__ align(CodeEntryAlignment);
|
||||||
|
StubId stub_id = StubId::stubgen_cipherBlockChaining_decryptAESCrypt_id;
|
||||||
|
StubCodeMark mark(this, stub_id);
|
||||||
|
|
||||||
|
const Register from = c_rarg0;
|
||||||
|
const Register to = c_rarg1;
|
||||||
|
const Register key = c_rarg2;
|
||||||
|
const Register rvec = c_rarg3;
|
||||||
|
const Register input_len = c_rarg4;
|
||||||
|
|
||||||
|
const Register keylen = x28;
|
||||||
|
|
||||||
|
address start = __ pc();
|
||||||
|
__ enter();
|
||||||
|
|
||||||
|
Label L_aes128, L_aes192, L_aes128_loop, L_aes192_loop, L_aes256_loop;
|
||||||
|
// Compute #rounds for AES based on the length of the key array
|
||||||
|
__ lwu(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
|
||||||
|
__ mv(t0, 52);
|
||||||
|
__ bltu(keylen, t0, L_aes128);
|
||||||
|
__ beq(keylen, t0, L_aes192);
|
||||||
|
// Else we fallthrough to the biggest case (256-bit key size)
|
||||||
|
|
||||||
|
// Note: the following function performs key += 15*16
|
||||||
|
cipherBlockChaining_decryptAESCrypt(15, from, to, key, rvec, input_len);
|
||||||
|
|
||||||
|
// Note: the following function performs key += 11*16
|
||||||
|
__ bind(L_aes128);
|
||||||
|
cipherBlockChaining_decryptAESCrypt(11, from, to, key, rvec, input_len);
|
||||||
|
|
||||||
|
// Note: the following function performs key += 13*16
|
||||||
|
__ bind(L_aes192);
|
||||||
|
cipherBlockChaining_decryptAESCrypt(13, from, to, key, rvec, input_len);
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load big-endian 128-bit from memory.
|
||||||
|
void be_load_counter_128(Register counter_hi, Register counter_lo, Register counter) {
|
||||||
|
__ ld(counter_lo, Address(counter, 8)); // Load 128-bits from counter
|
||||||
|
__ ld(counter_hi, Address(counter));
|
||||||
|
__ rev8(counter_lo, counter_lo); // Convert big-endian to little-endian
|
||||||
|
__ rev8(counter_hi, counter_hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Little-endian 128-bit + 64-bit -> 128-bit addition.
|
||||||
|
void add_counter_128(Register counter_hi, Register counter_lo) {
|
||||||
|
assert_different_registers(counter_hi, counter_lo, t0);
|
||||||
|
__ addi(counter_lo, counter_lo, 1);
|
||||||
|
__ seqz(t0, counter_lo); // Check for result overflow
|
||||||
|
__ add(counter_hi, counter_hi, t0); // Add 1 if overflow otherwise 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store big-endian 128-bit to memory.
|
||||||
|
void be_store_counter_128(Register counter_hi, Register counter_lo, Register counter) {
|
||||||
|
assert_different_registers(counter_hi, counter_lo, t0, t1);
|
||||||
|
__ rev8(t0, counter_lo); // Convert little-endian to big-endian
|
||||||
|
__ rev8(t1, counter_hi);
|
||||||
|
__ sd(t0, Address(counter, 8)); // Store 128-bits to counter
|
||||||
|
__ sd(t1, Address(counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
void counterMode_AESCrypt(int round, Register in, Register out, Register key, Register counter,
|
||||||
|
Register input_len, Register saved_encrypted_ctr, Register used_ptr) {
|
||||||
|
// Algorithm:
|
||||||
|
//
|
||||||
|
// generate_aes_loadkeys();
|
||||||
|
// load_counter_128(counter_hi, counter_lo, counter);
|
||||||
|
//
|
||||||
|
// L_next:
|
||||||
|
// if (used >= BLOCK_SIZE) goto L_main_loop;
|
||||||
|
//
|
||||||
|
// L_encrypt_next:
|
||||||
|
// *out = *in ^ saved_encrypted_ctr[used]);
|
||||||
|
// out++; in++; used++; len--;
|
||||||
|
// if (len == 0) goto L_exit;
|
||||||
|
// goto L_next;
|
||||||
|
//
|
||||||
|
// L_main_loop:
|
||||||
|
// if (len == 0) goto L_exit;
|
||||||
|
// saved_encrypted_ctr = generate_aes_encrypt(counter);
|
||||||
|
//
|
||||||
|
// add_counter_128(counter_hi, counter_lo);
|
||||||
|
// be_store_counter_128(counter_hi, counter_lo, counter);
|
||||||
|
// used = 0;
|
||||||
|
//
|
||||||
|
// if(len < BLOCK_SIZE) goto L_encrypt_next;
|
||||||
|
//
|
||||||
|
// v_in = load_16Byte(in);
|
||||||
|
// v_out = load_16Byte(out);
|
||||||
|
// v_saved_encrypted_ctr = load_16Byte(saved_encrypted_ctr);
|
||||||
|
// v_out = v_in ^ v_saved_encrypted_ctr;
|
||||||
|
// out += BLOCK_SIZE;
|
||||||
|
// in += BLOCK_SIZE;
|
||||||
|
// len -= BLOCK_SIZE;
|
||||||
|
// used = BLOCK_SIZE;
|
||||||
|
// goto L_main_loop;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// L_exit:
|
||||||
|
// store(used);
|
||||||
|
// result = input_len
|
||||||
|
// return result;
|
||||||
|
|
||||||
|
const Register used = x28;
|
||||||
|
const Register len = x29;
|
||||||
|
const Register counter_hi = x30;
|
||||||
|
const Register counter_lo = x31;
|
||||||
|
const Register block_size = t2;
|
||||||
|
|
||||||
|
const unsigned int BLOCK_SIZE = 16;
|
||||||
|
|
||||||
|
VectorRegister working_vregs[] = {
|
||||||
|
v1, v2, v3, v4, v5, v6, v7, v8,
|
||||||
|
v9, v10, v11, v12, v13, v14, v15
|
||||||
|
};
|
||||||
|
|
||||||
|
__ vsetivli(x0, 4, Assembler::e32, Assembler::m1);
|
||||||
|
|
||||||
|
__ lwu(used, Address(used_ptr));
|
||||||
|
__ mv(len, input_len);
|
||||||
|
__ mv(block_size, BLOCK_SIZE);
|
||||||
|
|
||||||
|
// load keys to working_vregs according to round
|
||||||
|
generate_aes_loadkeys(key, working_vregs, round);
|
||||||
|
|
||||||
|
// 128-bit big-endian load
|
||||||
|
be_load_counter_128(counter_hi, counter_lo, counter);
|
||||||
|
|
||||||
|
Label L_next, L_encrypt_next, L_main_loop, L_exit;
|
||||||
|
// Check the last saved_encrypted_ctr used value, we fall through
|
||||||
|
// to L_encrypt_next when the used value lower than block_size
|
||||||
|
__ bind(L_next);
|
||||||
|
__ bgeu(used, block_size, L_main_loop);
|
||||||
|
|
||||||
|
// There is still data left fewer than block_size after L_main_loop
|
||||||
|
// or last used, we encrypt them one by one.
|
||||||
|
__ bind(L_encrypt_next);
|
||||||
|
__ add(t0, saved_encrypted_ctr, used);
|
||||||
|
__ lbu(t1, Address(t0));
|
||||||
|
__ lbu(t0, Address(in));
|
||||||
|
__ xorr(t1, t1, t0);
|
||||||
|
__ sb(t1, Address(out));
|
||||||
|
__ addi(in, in, 1);
|
||||||
|
__ addi(out, out, 1);
|
||||||
|
__ addi(used, used, 1);
|
||||||
|
__ subi(len, len, 1);
|
||||||
|
__ beqz(len, L_exit);
|
||||||
|
__ j(L_next);
|
||||||
|
|
||||||
|
// We will calculate the next saved_encrypted_ctr and encrypt the blocks of data
|
||||||
|
// one by one until there is less than a full block remaining if len not zero
|
||||||
|
__ bind(L_main_loop);
|
||||||
|
__ beqz(len, L_exit);
|
||||||
|
__ vle32_v(v16, counter);
|
||||||
|
|
||||||
|
// encrypt counter according to round
|
||||||
|
generate_aes_encrypt(v16, working_vregs, round);
|
||||||
|
|
||||||
|
__ vse32_v(v16, saved_encrypted_ctr);
|
||||||
|
|
||||||
|
// 128-bit little-endian increment
|
||||||
|
add_counter_128(counter_hi, counter_lo);
|
||||||
|
// 128-bit big-endian store
|
||||||
|
be_store_counter_128(counter_hi, counter_lo, counter);
|
||||||
|
|
||||||
|
__ mv(used, 0);
|
||||||
|
// Check if we have a full block_size
|
||||||
|
__ bltu(len, block_size, L_encrypt_next);
|
||||||
|
|
||||||
|
// We have one full block to encrypt at least
|
||||||
|
__ vle32_v(v17, in);
|
||||||
|
__ vxor_vv(v16, v16, v17);
|
||||||
|
__ vse32_v(v16, out);
|
||||||
|
__ add(out, out, block_size);
|
||||||
|
__ add(in, in, block_size);
|
||||||
|
__ sub(len, len, block_size);
|
||||||
|
__ mv(used, block_size);
|
||||||
|
__ j(L_main_loop);
|
||||||
|
|
||||||
|
__ bind(L_exit);
|
||||||
|
__ sw(used, Address(used_ptr));
|
||||||
|
__ mv(x10, input_len);
|
||||||
|
__ leave();
|
||||||
|
__ ret();
|
||||||
|
};
|
||||||
|
|
||||||
|
// CTR AES crypt.
|
||||||
|
// Arguments:
|
||||||
|
//
|
||||||
|
// Inputs:
|
||||||
|
// c_rarg0 - source byte array address
|
||||||
|
// c_rarg1 - destination byte array address
|
||||||
|
// c_rarg2 - K (key) in little endian int array
|
||||||
|
// c_rarg3 - counter vector byte array address
|
||||||
|
// c_rarg4 - input length
|
||||||
|
// c_rarg5 - saved encryptedCounter start
|
||||||
|
// c_rarg6 - saved used length
|
||||||
|
//
|
||||||
|
// Output:
|
||||||
|
// x10 - input length
|
||||||
|
//
|
||||||
|
address generate_counterMode_AESCrypt() {
|
||||||
|
assert(UseAESCTRIntrinsics, "Must be");
|
||||||
|
assert(UseZvkn, "need AES instructions (Zvkned extension) support");
|
||||||
|
assert(UseZbb, "need basic bit manipulation (Zbb extension) support");
|
||||||
|
|
||||||
|
__ align(CodeEntryAlignment);
|
||||||
|
StubId stub_id = StubId::stubgen_counterMode_AESCrypt_id;
|
||||||
|
StubCodeMark mark(this, stub_id);
|
||||||
|
|
||||||
|
const Register in = c_rarg0;
|
||||||
|
const Register out = c_rarg1;
|
||||||
|
const Register key = c_rarg2;
|
||||||
|
const Register counter = c_rarg3;
|
||||||
|
const Register input_len = c_rarg4;
|
||||||
|
const Register saved_encrypted_ctr = c_rarg5;
|
||||||
|
const Register used_len_ptr = c_rarg6;
|
||||||
|
|
||||||
|
const Register keylen = c_rarg7; // temporary register
|
||||||
|
|
||||||
|
const address start = __ pc();
|
||||||
|
__ enter();
|
||||||
|
|
||||||
|
Label L_exit;
|
||||||
|
__ beqz(input_len, L_exit);
|
||||||
|
|
||||||
|
Label L_aes128, L_aes192;
|
||||||
|
// Compute #rounds for AES based on the length of the key array
|
||||||
|
__ lwu(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
|
||||||
|
__ mv(t0, 52); // key length could be only {11, 13, 15} * 4 = {44, 52, 60}
|
||||||
|
__ bltu(keylen, t0, L_aes128);
|
||||||
|
__ beq(keylen, t0, L_aes192);
|
||||||
|
// Else we fallthrough to the biggest case (256-bit key size)
|
||||||
|
|
||||||
|
// Note: the following function performs crypt with key += 15*16
|
||||||
|
counterMode_AESCrypt(15, in, out, key, counter, input_len, saved_encrypted_ctr, used_len_ptr);
|
||||||
|
|
||||||
|
// Note: the following function performs crypt with key += 13*16
|
||||||
|
__ bind(L_aes192);
|
||||||
|
counterMode_AESCrypt(13, in, out, key, counter, input_len, saved_encrypted_ctr, used_len_ptr);
|
||||||
|
|
||||||
|
// Note: the following function performs crypt with key += 11*16
|
||||||
|
__ bind(L_aes128);
|
||||||
|
counterMode_AESCrypt(11, in, out, key, counter, input_len, saved_encrypted_ctr, used_len_ptr);
|
||||||
|
|
||||||
|
__ bind(L_exit);
|
||||||
|
__ mv(x10, input_len);
|
||||||
|
__ leave();
|
||||||
|
__ ret();
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
// code for comparing 8 characters of strings with Latin1 and Utf16 encoding
|
// code for comparing 8 characters of strings with Latin1 and Utf16 encoding
|
||||||
void compare_string_8_x_LU(Register tmpL, Register tmpU,
|
void compare_string_8_x_LU(Register tmpL, Register tmpU,
|
||||||
Register strL, Register strU, Label& DIFF) {
|
Register strL, Register strU, Label& DIFF) {
|
||||||
@@ -6824,6 +7219,12 @@ static const int64_t right_3_bits = right_n_bits(3);
|
|||||||
if (UseAESIntrinsics) {
|
if (UseAESIntrinsics) {
|
||||||
StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
|
StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
|
||||||
StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();
|
StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();
|
||||||
|
StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
|
||||||
|
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UseAESCTRIntrinsics) {
|
||||||
|
StubRoutines::_counterMode_AESCrypt = generate_counterMode_AESCrypt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UsePoly1305Intrinsics) {
|
if (UsePoly1305Intrinsics) {
|
||||||
|
|||||||
@@ -434,6 +434,15 @@ void VM_Version::c2_initialize() {
|
|||||||
warning("UseAESIntrinsics enabled, but UseAES not, enabling");
|
warning("UseAESIntrinsics enabled, but UseAES not, enabling");
|
||||||
UseAES = true;
|
UseAES = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (FLAG_IS_DEFAULT(UseAESCTRIntrinsics) && UseZbb) {
|
||||||
|
FLAG_SET_DEFAULT(UseAESCTRIntrinsics, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UseAESCTRIntrinsics && !UseZbb) {
|
||||||
|
warning("Cannot enable UseAESCTRIntrinsics on cpu without UseZbb support.");
|
||||||
|
FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (UseAES) {
|
if (UseAES) {
|
||||||
warning("AES instructions are not available on this CPU");
|
warning("AES instructions are not available on this CPU");
|
||||||
@@ -443,11 +452,10 @@ void VM_Version::c2_initialize() {
|
|||||||
warning("AES intrinsics are not available on this CPU");
|
warning("AES intrinsics are not available on this CPU");
|
||||||
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
|
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
|
||||||
}
|
}
|
||||||
}
|
if (UseAESCTRIntrinsics) {
|
||||||
|
warning("Cannot enable UseAESCTRIntrinsics on cpu without UseZvkn support.");
|
||||||
if (UseAESCTRIntrinsics) {
|
FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
|
||||||
warning("AES/CTR intrinsics are not available on this CPU");
|
}
|
||||||
FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1715,6 +1715,8 @@ bool Matcher::match_rule_supported(int opcode) {
|
|||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case Op_ReverseBytesI:
|
case Op_ReverseBytesI:
|
||||||
case Op_ReverseBytesL:
|
case Op_ReverseBytesL:
|
||||||
|
case Op_ReverseBytesS:
|
||||||
|
case Op_ReverseBytesUS:
|
||||||
return UseByteReverseInstruction;
|
return UseByteReverseInstruction;
|
||||||
case Op_PopCountI:
|
case Op_PopCountI:
|
||||||
case Op_PopCountL:
|
case Op_PopCountL:
|
||||||
@@ -1865,6 +1867,10 @@ bool Matcher::is_reg2reg_move(MachNode* m) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Matcher::is_register_biasing_candidate(const MachNode* mdef, int oper_index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Matcher::is_generic_vector(MachOper* opnd) {
|
bool Matcher::is_generic_vector(MachOper* opnd) {
|
||||||
ShouldNotReachHere(); // generic vector operands not supported
|
ShouldNotReachHere(); // generic vector operands not supported
|
||||||
return false;
|
return false;
|
||||||
@@ -11611,6 +11617,38 @@ instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{
|
|||||||
|
|
||||||
// Byte reverse
|
// Byte reverse
|
||||||
|
|
||||||
|
instruct bytes_reverse_short(iRegI dst, iRegI src) %{
|
||||||
|
match(Set dst (ReverseBytesS src));
|
||||||
|
predicate(UseByteReverseInstruction);
|
||||||
|
ins_cost(2 * DEFAULT_COST);
|
||||||
|
size(8);
|
||||||
|
|
||||||
|
format %{ "LRVR $dst, $src\n\t # byte reverse int"
|
||||||
|
"SRA $dst, 0x0010\t # right shift by 16, sign extended" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ z_lrvr($dst$$Register, $src$$Register);
|
||||||
|
__ z_sra($dst$$Register, 0x0010);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_dummy);
|
||||||
|
%}
|
||||||
|
|
||||||
|
instruct bytes_reverse_unsigned_short(iRegI dst, iRegI src) %{
|
||||||
|
match(Set dst (ReverseBytesUS src));
|
||||||
|
predicate(UseByteReverseInstruction);
|
||||||
|
ins_cost(2 * DEFAULT_COST);
|
||||||
|
size(8);
|
||||||
|
|
||||||
|
format %{ "LRVR $dst, $src\n\t # byte reverse int"
|
||||||
|
"SRL $dst, 0x0010\t # right shift by 16, zero extended" %}
|
||||||
|
|
||||||
|
ins_encode %{
|
||||||
|
__ z_lrvr($dst$$Register, $src$$Register);
|
||||||
|
__ z_srl($dst$$Register, 0x0010);
|
||||||
|
%}
|
||||||
|
ins_pipe(pipe_class_dummy);
|
||||||
|
%}
|
||||||
|
|
||||||
instruct bytes_reverse_int(iRegI dst, iRegI src) %{
|
instruct bytes_reverse_int(iRegI dst, iRegI src) %{
|
||||||
match(Set dst (ReverseBytesI src));
|
match(Set dst (ReverseBytesI src));
|
||||||
predicate(UseByteReverseInstruction); // See Matcher::match_rule_supported
|
predicate(UseByteReverseInstruction); // See Matcher::match_rule_supported
|
||||||
|
|||||||
@@ -449,8 +449,8 @@ const int FPUStateSizeInWords = 2688 / wordSize;
|
|||||||
// imm8[1:0] = 00 (min) / 01 (max)
|
// imm8[1:0] = 00 (min) / 01 (max)
|
||||||
//
|
//
|
||||||
// [1] https://www.intel.com/content/www/us/en/content-details/856721/intel-advanced-vector-extensions-10-2-intel-avx10-2-architecture-specification.html?wapkw=AVX10
|
// [1] https://www.intel.com/content/www/us/en/content-details/856721/intel-advanced-vector-extensions-10-2-intel-avx10-2-architecture-specification.html?wapkw=AVX10
|
||||||
const int AVX10_MINMAX_MAX_COMPARE_SIGN = 0x5;
|
const int AVX10_2_MINMAX_MAX_COMPARE_SIGN = 0x5;
|
||||||
const int AVX10_MINMAX_MIN_COMPARE_SIGN = 0x4;
|
const int AVX10_2_MINMAX_MIN_COMPARE_SIGN = 0x4;
|
||||||
|
|
||||||
// The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction
|
// The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction
|
||||||
// level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write
|
// level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write
|
||||||
|
|||||||
@@ -1033,8 +1033,8 @@ void C2_MacroAssembler::vminmax_fp(int opc, BasicType elem_bt, XMMRegister dst,
|
|||||||
assert(opc == Op_MinV || opc == Op_MinReductionV ||
|
assert(opc == Op_MinV || opc == Op_MinReductionV ||
|
||||||
opc == Op_MaxV || opc == Op_MaxReductionV, "sanity");
|
opc == Op_MaxV || opc == Op_MaxReductionV, "sanity");
|
||||||
|
|
||||||
int imm8 = (opc == Op_MinV || opc == Op_MinReductionV) ? AVX10_MINMAX_MIN_COMPARE_SIGN
|
int imm8 = (opc == Op_MinV || opc == Op_MinReductionV) ? AVX10_2_MINMAX_MIN_COMPARE_SIGN
|
||||||
: AVX10_MINMAX_MAX_COMPARE_SIGN;
|
: AVX10_2_MINMAX_MAX_COMPARE_SIGN;
|
||||||
if (elem_bt == T_FLOAT) {
|
if (elem_bt == T_FLOAT) {
|
||||||
evminmaxps(dst, mask, src1, src2, true, imm8, vlen_enc);
|
evminmaxps(dst, mask, src1, src2, true, imm8, vlen_enc);
|
||||||
} else {
|
} else {
|
||||||
@@ -5163,7 +5163,7 @@ void C2_MacroAssembler::vector_castD2X_evex(BasicType to_elem_bt, XMMRegister ds
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C2_MacroAssembler::vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc) {
|
void C2_MacroAssembler::vector_castF2X_avx10_2(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc) {
|
||||||
switch(to_elem_bt) {
|
switch(to_elem_bt) {
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
evcvttps2qqs(dst, src, vec_enc);
|
evcvttps2qqs(dst, src, vec_enc);
|
||||||
@@ -5183,7 +5183,7 @@ void C2_MacroAssembler::vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C2_MacroAssembler::vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc) {
|
void C2_MacroAssembler::vector_castF2X_avx10_2(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc) {
|
||||||
switch(to_elem_bt) {
|
switch(to_elem_bt) {
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
evcvttps2qqs(dst, src, vec_enc);
|
evcvttps2qqs(dst, src, vec_enc);
|
||||||
@@ -5203,7 +5203,7 @@ void C2_MacroAssembler::vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C2_MacroAssembler::vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc) {
|
void C2_MacroAssembler::vector_castD2X_avx10_2(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc) {
|
||||||
switch(to_elem_bt) {
|
switch(to_elem_bt) {
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
evcvttpd2qqs(dst, src, vec_enc);
|
evcvttpd2qqs(dst, src, vec_enc);
|
||||||
@@ -5223,7 +5223,7 @@ void C2_MacroAssembler::vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C2_MacroAssembler::vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc) {
|
void C2_MacroAssembler::vector_castD2X_avx10_2(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc) {
|
||||||
switch(to_elem_bt) {
|
switch(to_elem_bt) {
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
evcvttpd2qqs(dst, src, vec_enc);
|
evcvttpd2qqs(dst, src, vec_enc);
|
||||||
|
|||||||
@@ -347,13 +347,13 @@ public:
|
|||||||
XMMRegister xtmp2, XMMRegister xtmp3, XMMRegister xtmp4, XMMRegister xtmp5,
|
XMMRegister xtmp2, XMMRegister xtmp3, XMMRegister xtmp4, XMMRegister xtmp5,
|
||||||
AddressLiteral float_sign_flip, Register rscratch, int vec_enc);
|
AddressLiteral float_sign_flip, Register rscratch, int vec_enc);
|
||||||
|
|
||||||
void vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc);
|
void vector_castF2X_avx10_2(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc);
|
||||||
|
|
||||||
void vector_castF2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc);
|
void vector_castF2X_avx10_2(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc);
|
||||||
|
|
||||||
void vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc);
|
void vector_castD2X_avx10_2(BasicType to_elem_bt, XMMRegister dst, XMMRegister src, int vec_enc);
|
||||||
|
|
||||||
void vector_castD2X_avx10(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc);
|
void vector_castD2X_avx10_2(BasicType to_elem_bt, XMMRegister dst, Address src, int vec_enc);
|
||||||
|
|
||||||
void vector_cast_double_to_int_special_cases_avx(XMMRegister dst, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2,
|
void vector_cast_double_to_int_special_cases_avx(XMMRegister dst, XMMRegister src, XMMRegister xtmp1, XMMRegister xtmp2,
|
||||||
XMMRegister xtmp3, XMMRegister xtmp4, XMMRegister xtmp5, Register rscratch,
|
XMMRegister xtmp3, XMMRegister xtmp4, XMMRegister xtmp5, Register rscratch,
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm
|
|||||||
|
|
||||||
void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
|
void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
|
||||||
Register addr, Register count, Register tmp) {
|
Register addr, Register count, Register tmp) {
|
||||||
Label done;
|
Label L_done;
|
||||||
|
|
||||||
__ testptr(count, count);
|
__ testptr(count, count);
|
||||||
__ jcc(Assembler::zero, done);
|
__ jccb(Assembler::zero, L_done);
|
||||||
|
|
||||||
// Calculate end address in "count".
|
// Calculate end address in "count".
|
||||||
Address::ScaleFactor scale = UseCompressedOops ? Address::times_4 : Address::times_8;
|
Address::ScaleFactor scale = UseCompressedOops ? Address::times_4 : Address::times_8;
|
||||||
@@ -111,31 +111,31 @@ void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* mas
|
|||||||
__ shrptr(count, CardTable::card_shift());
|
__ shrptr(count, CardTable::card_shift());
|
||||||
__ addptr(count, tmp);
|
__ addptr(count, tmp);
|
||||||
|
|
||||||
Label loop;
|
Label L_loop;
|
||||||
// Iterate from start card to end card (inclusive).
|
// Iterate from start card to end card (inclusive).
|
||||||
__ bind(loop);
|
__ bind(L_loop);
|
||||||
|
|
||||||
Label is_clean_card;
|
Label L_is_clean_card;
|
||||||
if (UseCondCardMark) {
|
if (UseCondCardMark) {
|
||||||
__ cmpb(Address(addr, 0), G1CardTable::clean_card_val());
|
__ cmpb(Address(addr, 0), G1CardTable::clean_card_val());
|
||||||
__ jcc(Assembler::equal, is_clean_card);
|
__ jccb(Assembler::equal, L_is_clean_card);
|
||||||
} else {
|
} else {
|
||||||
__ movb(Address(addr, 0), G1CardTable::dirty_card_val());
|
__ movb(Address(addr, 0), G1CardTable::dirty_card_val());
|
||||||
}
|
}
|
||||||
|
|
||||||
Label next_card;
|
Label L_next_card;
|
||||||
__ bind(next_card);
|
__ bind(L_next_card);
|
||||||
__ addptr(addr, sizeof(CardTable::CardValue));
|
__ addptr(addr, sizeof(CardTable::CardValue));
|
||||||
__ cmpptr(addr, count);
|
__ cmpptr(addr, count);
|
||||||
__ jcc(Assembler::belowEqual, loop);
|
__ jccb(Assembler::belowEqual, L_loop);
|
||||||
__ jmp(done);
|
__ jmpb(L_done);
|
||||||
|
|
||||||
__ bind(is_clean_card);
|
__ bind(L_is_clean_card);
|
||||||
// Card was clean. Dirty card and go to next..
|
// Card was clean. Dirty card and go to next.
|
||||||
__ movb(Address(addr, 0), G1CardTable::dirty_card_val());
|
__ movb(Address(addr, 0), G1CardTable::dirty_card_val());
|
||||||
__ jmp(next_card);
|
__ jmpb(L_next_card);
|
||||||
|
|
||||||
__ bind(done);
|
__ bind(L_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||||
@@ -157,22 +157,6 @@ void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void generate_queue_insertion(MacroAssembler* masm, ByteSize index_offset, ByteSize buffer_offset, Label& runtime,
|
|
||||||
const Register thread, const Register value, const Register temp) {
|
|
||||||
// This code assumes that buffer index is pointer sized.
|
|
||||||
STATIC_ASSERT(in_bytes(SATBMarkQueue::byte_width_of_index()) == sizeof(intptr_t));
|
|
||||||
// Can we store a value in the given thread's buffer?
|
|
||||||
// (The index field is typed as size_t.)
|
|
||||||
__ movptr(temp, Address(thread, in_bytes(index_offset))); // temp := *(index address)
|
|
||||||
__ testptr(temp, temp); // index == 0?
|
|
||||||
__ jcc(Assembler::zero, runtime); // jump to runtime if index == 0 (full buffer)
|
|
||||||
// The buffer is not full, store value into it.
|
|
||||||
__ subptr(temp, wordSize); // temp := next index
|
|
||||||
__ movptr(Address(thread, in_bytes(index_offset)), temp); // *(index address) := next index
|
|
||||||
__ addptr(temp, Address(thread, in_bytes(buffer_offset))); // temp := buffer address + next index
|
|
||||||
__ movptr(Address(temp, 0), value); // *(buffer address + next index) := value
|
|
||||||
}
|
|
||||||
|
|
||||||
static void generate_pre_barrier_fast_path(MacroAssembler* masm,
|
static void generate_pre_barrier_fast_path(MacroAssembler* masm,
|
||||||
const Register thread) {
|
const Register thread) {
|
||||||
Address in_progress(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
|
Address in_progress(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
|
||||||
@@ -190,21 +174,40 @@ static void generate_pre_barrier_slow_path(MacroAssembler* masm,
|
|||||||
const Register pre_val,
|
const Register pre_val,
|
||||||
const Register thread,
|
const Register thread,
|
||||||
const Register tmp,
|
const Register tmp,
|
||||||
Label& done,
|
Label& L_done) {
|
||||||
Label& runtime) {
|
Address index_addr(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
|
||||||
|
Address buffer_addr(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
|
||||||
|
|
||||||
|
// This code assumes that buffer index is pointer sized.
|
||||||
|
STATIC_ASSERT(in_bytes(SATBMarkQueue::byte_width_of_index()) == sizeof(intptr_t));
|
||||||
|
|
||||||
|
Label L_runtime;
|
||||||
|
|
||||||
// Do we need to load the previous value?
|
// Do we need to load the previous value?
|
||||||
if (obj != noreg) {
|
if (obj != noreg) {
|
||||||
__ load_heap_oop(pre_val, Address(obj, 0), noreg, AS_RAW);
|
__ load_heap_oop(pre_val, Address(obj, 0), noreg, AS_RAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the previous value null?
|
// Is the previous value null?
|
||||||
__ cmpptr(pre_val, NULL_WORD);
|
__ testptr(pre_val, pre_val);
|
||||||
__ jcc(Assembler::equal, done);
|
__ jcc(Assembler::equal, L_done);
|
||||||
generate_queue_insertion(masm,
|
|
||||||
G1ThreadLocalData::satb_mark_queue_index_offset(),
|
// Can we store a value in the given thread's buffer?
|
||||||
G1ThreadLocalData::satb_mark_queue_buffer_offset(),
|
// (The index field is typed as size_t.)
|
||||||
runtime,
|
__ movptr(tmp, index_addr); // temp := *(index address)
|
||||||
thread, pre_val, tmp);
|
__ testptr(tmp, tmp); // index == 0?
|
||||||
__ jmp(done);
|
__ jccb(Assembler::zero, L_runtime); // jump to runtime if index == 0 (full buffer)
|
||||||
|
|
||||||
|
// The buffer is not full, store value into it.
|
||||||
|
__ subptr(tmp, wordSize); // temp := next index
|
||||||
|
__ movptr(index_addr, tmp); // *(index address) := next index
|
||||||
|
__ addptr(tmp, buffer_addr); // temp := buffer address + next index
|
||||||
|
__ movptr(Address(tmp, 0), pre_val); // *(buffer address + next index) := value
|
||||||
|
|
||||||
|
// Jump out if done, or fall-through to runtime.
|
||||||
|
// "L_done" is far away, so jump cannot be short.
|
||||||
|
__ jmp(L_done);
|
||||||
|
__ bind(L_runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
|
void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
|
||||||
@@ -219,7 +222,6 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
|
|||||||
const Register thread = r15_thread;
|
const Register thread = r15_thread;
|
||||||
|
|
||||||
Label done;
|
Label done;
|
||||||
Label runtime;
|
|
||||||
|
|
||||||
assert(pre_val != noreg, "check this code");
|
assert(pre_val != noreg, "check this code");
|
||||||
|
|
||||||
@@ -231,9 +233,7 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
|
|||||||
generate_pre_barrier_fast_path(masm, thread);
|
generate_pre_barrier_fast_path(masm, thread);
|
||||||
// If marking is not active (*(mark queue active address) == 0), jump to done
|
// If marking is not active (*(mark queue active address) == 0), jump to done
|
||||||
__ jcc(Assembler::equal, done);
|
__ jcc(Assembler::equal, done);
|
||||||
generate_pre_barrier_slow_path(masm, obj, pre_val, thread, tmp, done, runtime);
|
generate_pre_barrier_slow_path(masm, obj, pre_val, thread, tmp, done);
|
||||||
|
|
||||||
__ bind(runtime);
|
|
||||||
|
|
||||||
// Determine and save the live input values
|
// Determine and save the live input values
|
||||||
__ push_call_clobbered_registers();
|
__ push_call_clobbered_registers();
|
||||||
@@ -272,23 +272,23 @@ static void generate_post_barrier(MacroAssembler* masm,
|
|||||||
const Register store_addr,
|
const Register store_addr,
|
||||||
const Register new_val,
|
const Register new_val,
|
||||||
const Register tmp1,
|
const Register tmp1,
|
||||||
Label& done,
|
|
||||||
bool new_val_may_be_null) {
|
bool new_val_may_be_null) {
|
||||||
|
|
||||||
assert_different_registers(store_addr, new_val, tmp1, noreg);
|
assert_different_registers(store_addr, new_val, tmp1, noreg);
|
||||||
|
|
||||||
Register thread = r15_thread;
|
Register thread = r15_thread;
|
||||||
|
|
||||||
|
Label L_done;
|
||||||
// Does store cross heap regions?
|
// Does store cross heap regions?
|
||||||
__ movptr(tmp1, store_addr); // tmp1 := store address
|
__ movptr(tmp1, store_addr); // tmp1 := store address
|
||||||
__ xorptr(tmp1, new_val); // tmp1 := store address ^ new value
|
__ xorptr(tmp1, new_val); // tmp1 := store address ^ new value
|
||||||
__ shrptr(tmp1, G1HeapRegion::LogOfHRGrainBytes); // ((store address ^ new value) >> LogOfHRGrainBytes) == 0?
|
__ shrptr(tmp1, G1HeapRegion::LogOfHRGrainBytes); // ((store address ^ new value) >> LogOfHRGrainBytes) == 0?
|
||||||
__ jcc(Assembler::equal, done);
|
__ jccb(Assembler::equal, L_done);
|
||||||
|
|
||||||
// Crosses regions, storing null?
|
// Crosses regions, storing null?
|
||||||
if (new_val_may_be_null) {
|
if (new_val_may_be_null) {
|
||||||
__ cmpptr(new_val, NULL_WORD); // new value == null?
|
__ testptr(new_val, new_val); // new value == null?
|
||||||
__ jcc(Assembler::equal, done);
|
__ jccb(Assembler::equal, L_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
__ movptr(tmp1, store_addr); // tmp1 := store address
|
__ movptr(tmp1, store_addr); // tmp1 := store address
|
||||||
@@ -298,20 +298,19 @@ static void generate_post_barrier(MacroAssembler* masm,
|
|||||||
__ addptr(tmp1, card_table_addr); // tmp1 := card address
|
__ addptr(tmp1, card_table_addr); // tmp1 := card address
|
||||||
if (UseCondCardMark) {
|
if (UseCondCardMark) {
|
||||||
__ cmpb(Address(tmp1, 0), G1CardTable::clean_card_val()); // *(card address) == clean_card_val?
|
__ cmpb(Address(tmp1, 0), G1CardTable::clean_card_val()); // *(card address) == clean_card_val?
|
||||||
__ jcc(Assembler::notEqual, done);
|
__ jccb(Assembler::notEqual, L_done);
|
||||||
}
|
}
|
||||||
// Storing a region crossing, non-null oop, card is clean.
|
// Storing a region crossing, non-null oop, card is clean.
|
||||||
// Dirty card.
|
// Dirty card.
|
||||||
__ movb(Address(tmp1, 0), G1CardTable::dirty_card_val()); // *(card address) := dirty_card_val
|
__ movb(Address(tmp1, 0), G1CardTable::dirty_card_val()); // *(card address) := dirty_card_val
|
||||||
|
__ bind(L_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
|
void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
|
||||||
Register store_addr,
|
Register store_addr,
|
||||||
Register new_val,
|
Register new_val,
|
||||||
Register tmp) {
|
Register tmp) {
|
||||||
Label done;
|
generate_post_barrier(masm, store_addr, new_val, tmp, true /* new_val_may_be_null */);
|
||||||
generate_post_barrier(masm, store_addr, new_val, tmp, done, true /* new_val_may_be_null */);
|
|
||||||
__ bind(done);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(COMPILER2)
|
#if defined(COMPILER2)
|
||||||
@@ -354,7 +353,6 @@ void G1BarrierSetAssembler::g1_write_barrier_pre_c2(MacroAssembler* masm,
|
|||||||
void G1BarrierSetAssembler::generate_c2_pre_barrier_stub(MacroAssembler* masm,
|
void G1BarrierSetAssembler::generate_c2_pre_barrier_stub(MacroAssembler* masm,
|
||||||
G1PreBarrierStubC2* stub) const {
|
G1PreBarrierStubC2* stub) const {
|
||||||
Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
|
Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
|
||||||
Label runtime;
|
|
||||||
Register obj = stub->obj();
|
Register obj = stub->obj();
|
||||||
Register pre_val = stub->pre_val();
|
Register pre_val = stub->pre_val();
|
||||||
Register thread = stub->thread();
|
Register thread = stub->thread();
|
||||||
@@ -362,9 +360,8 @@ void G1BarrierSetAssembler::generate_c2_pre_barrier_stub(MacroAssembler* masm,
|
|||||||
assert(stub->tmp2() == noreg, "not needed in this platform");
|
assert(stub->tmp2() == noreg, "not needed in this platform");
|
||||||
|
|
||||||
__ bind(*stub->entry());
|
__ bind(*stub->entry());
|
||||||
generate_pre_barrier_slow_path(masm, obj, pre_val, thread, tmp, *stub->continuation(), runtime);
|
generate_pre_barrier_slow_path(masm, obj, pre_val, thread, tmp, *stub->continuation());
|
||||||
|
|
||||||
__ bind(runtime);
|
|
||||||
generate_c2_barrier_runtime_call(masm, stub, pre_val, CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry));
|
generate_c2_barrier_runtime_call(masm, stub, pre_val, CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry));
|
||||||
__ jmp(*stub->continuation());
|
__ jmp(*stub->continuation());
|
||||||
}
|
}
|
||||||
@@ -374,9 +371,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm,
|
|||||||
Register new_val,
|
Register new_val,
|
||||||
Register tmp,
|
Register tmp,
|
||||||
bool new_val_may_be_null) {
|
bool new_val_may_be_null) {
|
||||||
Label done;
|
generate_post_barrier(masm, store_addr, new_val, tmp, new_val_may_be_null);
|
||||||
generate_post_barrier(masm, store_addr, new_val, tmp, done, new_val_may_be_null);
|
|
||||||
__ bind(done);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMPILER2
|
#endif // COMPILER2
|
||||||
@@ -449,7 +444,7 @@ void G1BarrierSetAssembler::gen_pre_barrier_stub(LIR_Assembler* ce, G1PreBarrier
|
|||||||
ce->mem2reg(stub->addr(), stub->pre_val(), T_OBJECT, stub->patch_code(), stub->info(), false /*wide*/);
|
ce->mem2reg(stub->addr(), stub->pre_val(), T_OBJECT, stub->patch_code(), stub->info(), false /*wide*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
__ cmpptr(pre_val_reg, NULL_WORD);
|
__ testptr(pre_val_reg, pre_val_reg);
|
||||||
__ jcc(Assembler::equal, *stub->continuation());
|
__ jcc(Assembler::equal, *stub->continuation());
|
||||||
ce->store_parameter(stub->pre_val()->as_register(), 0);
|
ce->store_parameter(stub->pre_val()->as_register(), 0);
|
||||||
__ call(RuntimeAddress(bs->pre_barrier_c1_runtime_code_blob()->code_begin()));
|
__ call(RuntimeAddress(bs->pre_barrier_c1_runtime_code_blob()->code_begin()));
|
||||||
@@ -465,9 +460,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post_c1(MacroAssembler* masm,
|
|||||||
Register thread,
|
Register thread,
|
||||||
Register tmp1,
|
Register tmp1,
|
||||||
Register tmp2 /* unused on x86 */) {
|
Register tmp2 /* unused on x86 */) {
|
||||||
Label done;
|
generate_post_barrier(masm, store_addr, new_val, tmp1, true /* new_val_may_be_null */);
|
||||||
generate_post_barrier(masm, store_addr, new_val, tmp1, done, true /* new_val_may_be_null */);
|
|
||||||
masm->bind(done);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __ sasm->
|
#define __ sasm->
|
||||||
@@ -490,8 +483,7 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler*
|
|||||||
Address queue_index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
|
Address queue_index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
|
||||||
Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
|
Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
|
||||||
|
|
||||||
Label done;
|
Label L_done, L_runtime;
|
||||||
Label runtime;
|
|
||||||
|
|
||||||
// Is marking still active?
|
// Is marking still active?
|
||||||
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
|
if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
|
||||||
@@ -500,13 +492,13 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler*
|
|||||||
assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
|
assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
|
||||||
__ cmpb(queue_active, 0);
|
__ cmpb(queue_active, 0);
|
||||||
}
|
}
|
||||||
__ jcc(Assembler::equal, done);
|
__ jcc(Assembler::equal, L_done);
|
||||||
|
|
||||||
// Can we store original value in the thread's buffer?
|
// Can we store original value in the thread's buffer?
|
||||||
|
|
||||||
__ movptr(tmp, queue_index);
|
__ movptr(tmp, queue_index);
|
||||||
__ testptr(tmp, tmp);
|
__ testptr(tmp, tmp);
|
||||||
__ jcc(Assembler::zero, runtime);
|
__ jccb(Assembler::zero, L_runtime);
|
||||||
__ subptr(tmp, wordSize);
|
__ subptr(tmp, wordSize);
|
||||||
__ movptr(queue_index, tmp);
|
__ movptr(queue_index, tmp);
|
||||||
__ addptr(tmp, buffer);
|
__ addptr(tmp, buffer);
|
||||||
@@ -514,9 +506,9 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler*
|
|||||||
// prev_val (rax)
|
// prev_val (rax)
|
||||||
__ load_parameter(0, pre_val);
|
__ load_parameter(0, pre_val);
|
||||||
__ movptr(Address(tmp, 0), pre_val);
|
__ movptr(Address(tmp, 0), pre_val);
|
||||||
__ jmp(done);
|
__ jmp(L_done);
|
||||||
|
|
||||||
__ bind(runtime);
|
__ bind(L_runtime);
|
||||||
|
|
||||||
__ push_call_clobbered_registers();
|
__ push_call_clobbered_registers();
|
||||||
|
|
||||||
@@ -526,7 +518,7 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler*
|
|||||||
|
|
||||||
__ pop_call_clobbered_registers();
|
__ pop_call_clobbered_registers();
|
||||||
|
|
||||||
__ bind(done);
|
__ bind(L_done);
|
||||||
|
|
||||||
__ pop_ppx(rdx);
|
__ pop_ppx(rdx);
|
||||||
__ pop_ppx(rax);
|
__ pop_ppx(rax);
|
||||||
|
|||||||
@@ -8899,9 +8899,9 @@ void MacroAssembler::evpmins(BasicType type, XMMRegister dst, KRegister mask, XM
|
|||||||
case T_LONG:
|
case T_LONG:
|
||||||
evpminsq(dst, mask, nds, src, merge, vector_len); break;
|
evpminsq(dst, mask, nds, src, merge, vector_len); break;
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
evminmaxps(dst, mask, nds, src, merge, AVX10_2_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
evminmaxpd(dst, mask, nds, src, merge, AVX10_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
evminmaxpd(dst, mask, nds, src, merge, AVX10_2_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
||||||
default:
|
default:
|
||||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||||
}
|
}
|
||||||
@@ -8918,9 +8918,9 @@ void MacroAssembler::evpmaxs(BasicType type, XMMRegister dst, KRegister mask, XM
|
|||||||
case T_LONG:
|
case T_LONG:
|
||||||
evpmaxsq(dst, mask, nds, src, merge, vector_len); break;
|
evpmaxsq(dst, mask, nds, src, merge, vector_len); break;
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
evminmaxps(dst, mask, nds, src, merge, AVX10_2_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
evminmaxpd(dst, mask, nds, src, merge, AVX10_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
evminmaxpd(dst, mask, nds, src, merge, AVX10_2_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
||||||
default:
|
default:
|
||||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||||
}
|
}
|
||||||
@@ -8937,9 +8937,9 @@ void MacroAssembler::evpmins(BasicType type, XMMRegister dst, KRegister mask, XM
|
|||||||
case T_LONG:
|
case T_LONG:
|
||||||
evpminsq(dst, mask, nds, src, merge, vector_len); break;
|
evpminsq(dst, mask, nds, src, merge, vector_len); break;
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
evminmaxps(dst, mask, nds, src, merge, AVX10_2_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
evminmaxpd(dst, mask, nds, src, merge, AVX10_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
evminmaxpd(dst, mask, nds, src, merge, AVX10_2_MINMAX_MIN_COMPARE_SIGN, vector_len); break;
|
||||||
default:
|
default:
|
||||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||||
}
|
}
|
||||||
@@ -8956,9 +8956,9 @@ void MacroAssembler::evpmaxs(BasicType type, XMMRegister dst, KRegister mask, XM
|
|||||||
case T_LONG:
|
case T_LONG:
|
||||||
evpmaxsq(dst, mask, nds, src, merge, vector_len); break;
|
evpmaxsq(dst, mask, nds, src, merge, vector_len); break;
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
evminmaxps(dst, mask, nds, src, merge, AVX10_2_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
evminmaxps(dst, mask, nds, src, merge, AVX10_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
evminmaxps(dst, mask, nds, src, merge, AVX10_2_MINMAX_MAX_COMPARE_SIGN, vector_len); break;
|
||||||
default:
|
default:
|
||||||
fatal("Unexpected type argument %s", type2name(type)); break;
|
fatal("Unexpected type argument %s", type2name(type)); break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@
|
|||||||
do_arch_blob, \
|
do_arch_blob, \
|
||||||
do_arch_entry, \
|
do_arch_entry, \
|
||||||
do_arch_entry_init) \
|
do_arch_entry_init) \
|
||||||
do_arch_blob(compiler, 109000 WINDOWS_ONLY(+2000)) \
|
do_arch_blob(compiler, 120000 WINDOWS_ONLY(+2000)) \
|
||||||
do_stub(compiler, vector_float_sign_mask) \
|
do_stub(compiler, vector_float_sign_mask) \
|
||||||
do_arch_entry(x86, compiler, vector_float_sign_mask, \
|
do_arch_entry(x86, compiler, vector_float_sign_mask, \
|
||||||
vector_float_sign_mask, vector_float_sign_mask) \
|
vector_float_sign_mask, vector_float_sign_mask) \
|
||||||
|
|||||||
@@ -480,7 +480,7 @@ address StubGenerator::generate_counterMode_VectorAESCrypt() {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKe (key) in little endian int array
|
||||||
// c_rarg3 - counter vector byte array address
|
// c_rarg3 - counter vector byte array address
|
||||||
// Linux
|
// Linux
|
||||||
// c_rarg4 - input length
|
// c_rarg4 - input length
|
||||||
@@ -1063,7 +1063,7 @@ address StubGenerator::generate_cipherBlockChaining_decryptVectorAESCrypt() {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKe (key) in little endian int array
|
||||||
//
|
//
|
||||||
address StubGenerator::generate_aescrypt_encryptBlock() {
|
address StubGenerator::generate_aescrypt_encryptBlock() {
|
||||||
assert(UseAES, "need AES instructions and misaligned SSE support");
|
assert(UseAES, "need AES instructions and misaligned SSE support");
|
||||||
@@ -1158,7 +1158,7 @@ address StubGenerator::generate_aescrypt_encryptBlock() {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKd (key) in little endian int array
|
||||||
//
|
//
|
||||||
address StubGenerator::generate_aescrypt_decryptBlock() {
|
address StubGenerator::generate_aescrypt_decryptBlock() {
|
||||||
assert(UseAES, "need AES instructions and misaligned SSE support");
|
assert(UseAES, "need AES instructions and misaligned SSE support");
|
||||||
@@ -1255,7 +1255,7 @@ address StubGenerator::generate_aescrypt_decryptBlock() {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKe (key) in little endian int array
|
||||||
// c_rarg3 - r vector byte array address
|
// c_rarg3 - r vector byte array address
|
||||||
// c_rarg4 - input length
|
// c_rarg4 - input length
|
||||||
//
|
//
|
||||||
@@ -1407,7 +1407,7 @@ address StubGenerator::generate_cipherBlockChaining_encryptAESCrypt() {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// c_rarg0 - source byte array address
|
// c_rarg0 - source byte array address
|
||||||
// c_rarg1 - destination byte array address
|
// c_rarg1 - destination byte array address
|
||||||
// c_rarg2 - K (key) in little endian int array
|
// c_rarg2 - sessionKd (key) in little endian int array
|
||||||
// c_rarg3 - r vector byte array address
|
// c_rarg3 - r vector byte array address
|
||||||
// c_rarg4 - input length
|
// c_rarg4 - input length
|
||||||
//
|
//
|
||||||
@@ -3524,10 +3524,10 @@ void StubGenerator::aesgcm_avx512(Register in, Register len, Register ct, Regist
|
|||||||
false, true, false, false, false, ghashin_offset, aesout_offset, HashKey_32);
|
false, true, false, false, false, ghashin_offset, aesout_offset, HashKey_32);
|
||||||
|
|
||||||
ghash16_avx512(false, true, false, false, true, in, pos, avx512_subkeyHtbl, AAD_HASHx, SHUF_MASK, stack_offset, 16 * 16, 0, HashKey_16);
|
ghash16_avx512(false, true, false, false, true, in, pos, avx512_subkeyHtbl, AAD_HASHx, SHUF_MASK, stack_offset, 16 * 16, 0, HashKey_16);
|
||||||
|
__ addl(pos, 16 * 16);
|
||||||
|
|
||||||
__ bind(MESG_BELOW_32_BLKS);
|
__ bind(MESG_BELOW_32_BLKS);
|
||||||
__ subl(len, 16 * 16);
|
__ subl(len, 16 * 16);
|
||||||
__ addl(pos, 16 * 16);
|
|
||||||
gcm_enc_dec_last_avx512(len, in, pos, AAD_HASHx, SHUF_MASK, avx512_subkeyHtbl, ghashin_offset, HashKey_16, true, true);
|
gcm_enc_dec_last_avx512(len, in, pos, AAD_HASHx, SHUF_MASK, avx512_subkeyHtbl, ghashin_offset, HashKey_16, true, true);
|
||||||
|
|
||||||
__ bind(GHASH_DONE);
|
__ bind(GHASH_DONE);
|
||||||
@@ -4016,13 +4016,15 @@ void StubGenerator::aesgcm_avx2(Register in, Register len, Register ct, Register
|
|||||||
const Register rounds = r10;
|
const Register rounds = r10;
|
||||||
const XMMRegister ctr_blockx = xmm9;
|
const XMMRegister ctr_blockx = xmm9;
|
||||||
const XMMRegister aad_hashx = xmm8;
|
const XMMRegister aad_hashx = xmm8;
|
||||||
Label encrypt_done, encrypt_by_8_new, encrypt_by_8;
|
Label encrypt_done, encrypt_by_8_new, encrypt_by_8, exit;
|
||||||
|
|
||||||
//This routine should be called only for message sizes of 128 bytes or more.
|
//This routine should be called only for message sizes of 128 bytes or more.
|
||||||
//Macro flow:
|
//Macro flow:
|
||||||
//process 8 16 byte blocks in initial_num_blocks.
|
//process 8 16 byte blocks in initial_num_blocks.
|
||||||
//process 8 16 byte blocks at a time until all are done 'encrypt_by_8_new followed by ghash_last_8'
|
//process 8 16 byte blocks at a time until all are done 'encrypt_by_8_new followed by ghash_last_8'
|
||||||
__ xorl(pos, pos);
|
__ xorl(pos, pos);
|
||||||
|
__ cmpl(len, 128);
|
||||||
|
__ jcc(Assembler::less, exit);
|
||||||
|
|
||||||
//Generate 8 constants for htbl
|
//Generate 8 constants for htbl
|
||||||
generateHtbl_8_block_avx2(subkeyHtbl);
|
generateHtbl_8_block_avx2(subkeyHtbl);
|
||||||
@@ -4090,6 +4092,7 @@ void StubGenerator::aesgcm_avx2(Register in, Register len, Register ct, Register
|
|||||||
__ vpxor(xmm0, xmm0, xmm0, Assembler::AVX_128bit);
|
__ vpxor(xmm0, xmm0, xmm0, Assembler::AVX_128bit);
|
||||||
__ vpxor(xmm13, xmm13, xmm13, Assembler::AVX_128bit);
|
__ vpxor(xmm13, xmm13, xmm13, Assembler::AVX_128bit);
|
||||||
|
|
||||||
|
__ bind(exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef __
|
#undef __
|
||||||
|
|||||||
@@ -2633,6 +2633,70 @@ bool Matcher::supports_vector_calling_convention(void) {
|
|||||||
return EnableVectorSupport;
|
return EnableVectorSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_ndd_demotable(const MachNode* mdef) {
|
||||||
|
return ((mdef->flags() & Node::PD::Flag_ndd_demotable) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_ndd_demotable_commutative(const MachNode* mdef) {
|
||||||
|
return ((mdef->flags() & Node::PD::Flag_ndd_demotable_commutative) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_demotion_candidate(const MachNode* mdef) {
|
||||||
|
return (is_ndd_demotable(mdef) || is_ndd_demotable_commutative(mdef));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Matcher::is_register_biasing_candidate(const MachNode* mdef,
|
||||||
|
int oper_index) {
|
||||||
|
if (mdef == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mdef->num_opnds() <= oper_index || mdef->operand_index(oper_index) < 0 ||
|
||||||
|
mdef->in(mdef->operand_index(oper_index)) == nullptr) {
|
||||||
|
assert(oper_index != 1 || !is_demotion_candidate(mdef), "%s", mdef->Name());
|
||||||
|
assert(oper_index != 2 || !is_ndd_demotable_commutative(mdef), "%s", mdef->Name());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complex memory operand covers multiple incoming edges needed for
|
||||||
|
// address computation. Biasing def towards any address component will not
|
||||||
|
// result in NDD demotion by assembler.
|
||||||
|
if (mdef->operand_num_edges(oper_index) != 1) {
|
||||||
|
assert(!is_ndd_demotable(mdef), "%s", mdef->Name());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Demotion candidate must be register mask compatible with definition.
|
||||||
|
const RegMask& oper_mask = mdef->in_RegMask(mdef->operand_index(oper_index));
|
||||||
|
if (!oper_mask.overlap(mdef->out_RegMask())) {
|
||||||
|
assert(!is_demotion_candidate(mdef), "%s", mdef->Name());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (oper_index) {
|
||||||
|
// First operand of MachNode corresponding to Intel APX NDD selection
|
||||||
|
// pattern can share its assigned register with definition operand if
|
||||||
|
// their live ranges do not overlap. In such a scenario we can demote
|
||||||
|
// it to legacy map0/map1 instruction by replacing its 4-byte extended
|
||||||
|
// EVEX prefix with shorter REX/REX2 encoding. Demotion candidates
|
||||||
|
// are decorated with a special flag by instruction selector.
|
||||||
|
case 1:
|
||||||
|
return is_demotion_candidate(mdef);
|
||||||
|
|
||||||
|
// Definition operand of commutative operation can be biased towards second
|
||||||
|
// operand.
|
||||||
|
case 2:
|
||||||
|
return is_ndd_demotable_commutative(mdef);
|
||||||
|
|
||||||
|
// Current scheme only selects up to two biasing candidates
|
||||||
|
default:
|
||||||
|
assert(false, "unhandled operand index: %s", mdef->Name());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
|
OptoRegPair Matcher::vector_return_value(uint ideal_reg) {
|
||||||
assert(EnableVectorSupport, "sanity");
|
assert(EnableVectorSupport, "sanity");
|
||||||
int lo = XMM0_num;
|
int lo = XMM0_num;
|
||||||
@@ -2812,7 +2876,7 @@ static inline bool is_clz_non_subword_predicate_evex(BasicType bt, int vlen_byte
|
|||||||
|
|
||||||
class Node::PD {
|
class Node::PD {
|
||||||
public:
|
public:
|
||||||
enum NodeFlags {
|
enum NodeFlags : uint64_t {
|
||||||
Flag_intel_jcc_erratum = Node::_last_flag << 1,
|
Flag_intel_jcc_erratum = Node::_last_flag << 1,
|
||||||
Flag_sets_carry_flag = Node::_last_flag << 2,
|
Flag_sets_carry_flag = Node::_last_flag << 2,
|
||||||
Flag_sets_parity_flag = Node::_last_flag << 3,
|
Flag_sets_parity_flag = Node::_last_flag << 3,
|
||||||
@@ -2824,7 +2888,9 @@ public:
|
|||||||
Flag_clears_zero_flag = Node::_last_flag << 9,
|
Flag_clears_zero_flag = Node::_last_flag << 9,
|
||||||
Flag_clears_overflow_flag = Node::_last_flag << 10,
|
Flag_clears_overflow_flag = Node::_last_flag << 10,
|
||||||
Flag_clears_sign_flag = Node::_last_flag << 11,
|
Flag_clears_sign_flag = Node::_last_flag << 11,
|
||||||
_last_flag = Flag_clears_sign_flag
|
Flag_ndd_demotable = Node::_last_flag << 12,
|
||||||
|
Flag_ndd_demotable_commutative = Node::_last_flag << 13,
|
||||||
|
_last_flag = Flag_ndd_demotable_commutative
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3320,6 +3386,11 @@ bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType bt) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Op_VectorBlend:
|
||||||
|
if (UseAVX == 0 && size_in_bits < 128) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case Op_VectorTest:
|
case Op_VectorTest:
|
||||||
if (UseSSE < 4) {
|
if (UseSSE < 4) {
|
||||||
return false; // Implementation limitation
|
return false; // Implementation limitation
|
||||||
@@ -7218,12 +7289,12 @@ instruct loadD(regD dst, memory mem)
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// max = java.lang.Math.max(float a, float b)
|
// max = java.lang.Math.max(float a, float b)
|
||||||
instruct maxF_avx10_reg(regF dst, regF a, regF b) %{
|
instruct maxF_reg_avx10_2(regF dst, regF a, regF b) %{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (MaxF a b));
|
match(Set dst (MaxF a b));
|
||||||
format %{ "maxF $dst, $a, $b" %}
|
format %{ "maxF $dst, $a, $b" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
__ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN);
|
__ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_2_MINMAX_MAX_COMPARE_SIGN);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
@@ -7254,12 +7325,12 @@ instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRe
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// max = java.lang.Math.max(double a, double b)
|
// max = java.lang.Math.max(double a, double b)
|
||||||
instruct maxD_avx10_reg(regD dst, regD a, regD b) %{
|
instruct maxD_reg_avx10_2(regD dst, regD a, regD b) %{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (MaxD a b));
|
match(Set dst (MaxD a b));
|
||||||
format %{ "maxD $dst, $a, $b" %}
|
format %{ "maxD $dst, $a, $b" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
__ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN);
|
__ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_2_MINMAX_MAX_COMPARE_SIGN);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
@@ -7290,12 +7361,12 @@ instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRe
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// max = java.lang.Math.min(float a, float b)
|
// max = java.lang.Math.min(float a, float b)
|
||||||
instruct minF_avx10_reg(regF dst, regF a, regF b) %{
|
instruct minF_reg_avx10_2(regF dst, regF a, regF b) %{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (MinF a b));
|
match(Set dst (MinF a b));
|
||||||
format %{ "minF $dst, $a, $b" %}
|
format %{ "minF $dst, $a, $b" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
__ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN);
|
__ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_2_MINMAX_MIN_COMPARE_SIGN);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
@@ -7326,12 +7397,12 @@ instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRe
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// max = java.lang.Math.min(double a, double b)
|
// max = java.lang.Math.min(double a, double b)
|
||||||
instruct minD_avx10_reg(regD dst, regD a, regD b) %{
|
instruct minD_reg_avx10_2(regD dst, regD a, regD b) %{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (MinD a b));
|
match(Set dst (MinD a b));
|
||||||
format %{ "minD $dst, $a, $b" %}
|
format %{ "minD $dst, $a, $b" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
__ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN);
|
__ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_2_MINMAX_MIN_COMPARE_SIGN);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
@@ -9801,7 +9872,7 @@ instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AddI src1 src2));
|
match(Set dst (AddI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -9829,7 +9900,7 @@ instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AddI src1 src2));
|
match(Set dst (AddI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -9872,7 +9943,7 @@ instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AddI src1 (LoadI src2)));
|
match(Set dst (AddI src1 (LoadI src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
|
||||||
@@ -9929,6 +10000,7 @@ instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr)
|
|||||||
predicate(UseAPX && UseIncDec);
|
predicate(UseAPX && UseIncDec);
|
||||||
match(Set dst (AddI src val));
|
match(Set dst (AddI src val));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eincl $dst, $src\t# int ndd" %}
|
format %{ "eincl $dst, $src\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -9983,6 +10055,7 @@ instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr)
|
|||||||
predicate(UseAPX && UseIncDec);
|
predicate(UseAPX && UseIncDec);
|
||||||
match(Set dst (AddI src val));
|
match(Set dst (AddI src val));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "edecl $dst, $src\t# int ndd" %}
|
format %{ "edecl $dst, $src\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -10089,7 +10162,7 @@ instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AddL src1 src2));
|
match(Set dst (AddL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -10117,7 +10190,7 @@ instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AddL src1 src2));
|
match(Set dst (AddL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -10160,7 +10233,7 @@ instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AddL src1 (LoadL src2)));
|
match(Set dst (AddL src1 (LoadL src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
|
||||||
@@ -10216,6 +10289,7 @@ instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr)
|
|||||||
predicate(UseAPX && UseIncDec);
|
predicate(UseAPX && UseIncDec);
|
||||||
match(Set dst (AddL src val));
|
match(Set dst (AddL src val));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eincq $dst, $src\t# long ndd" %}
|
format %{ "eincq $dst, $src\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -10270,6 +10344,7 @@ instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr)
|
|||||||
predicate(UseAPX && UseIncDec);
|
predicate(UseAPX && UseIncDec);
|
||||||
match(Set dst (AddL src val));
|
match(Set dst (AddL src val));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "edecq $dst, $src\t# long ndd" %}
|
format %{ "edecq $dst, $src\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -10984,7 +11059,7 @@ instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (SubI src1 src2));
|
match(Set dst (SubI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -10998,7 +11073,7 @@ instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (SubI src1 src2));
|
match(Set dst (SubI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -11041,7 +11116,7 @@ instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (SubI src1 (LoadI src2)));
|
match(Set dst (SubI src1 (LoadI src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
|
||||||
@@ -11099,7 +11174,7 @@ instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (SubL src1 src2));
|
match(Set dst (SubL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -11113,7 +11188,7 @@ instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (SubL src1 src2));
|
match(Set dst (SubL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -11156,7 +11231,7 @@ instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (SubL src1 (LoadL src2)));
|
match(Set dst (SubL src1 (LoadL src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
|
||||||
@@ -11228,7 +11303,7 @@ instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (SubI zero src));
|
match(Set dst (SubI zero src));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "enegl $dst, $src\t# int ndd" %}
|
format %{ "enegl $dst, $src\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -11256,7 +11331,7 @@ instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (NegI src));
|
match(Set dst (NegI src));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "enegl $dst, $src\t# int ndd" %}
|
format %{ "enegl $dst, $src\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -11297,7 +11372,7 @@ instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (SubL zero src));
|
match(Set dst (SubL zero src));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "enegq $dst, $src\t# long ndd" %}
|
format %{ "enegq $dst, $src\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -11325,7 +11400,7 @@ instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (NegL src));
|
match(Set dst (NegL src));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag);
|
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "enegq $dst, $src\t# long ndd" %}
|
format %{ "enegq $dst, $src\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -11370,6 +11445,7 @@ instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (MulI src1 src2));
|
match(Set dst (MulI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
ins_cost(300);
|
ins_cost(300);
|
||||||
format %{ "eimull $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eimull $dst, $src1, $src2\t# int ndd" %}
|
||||||
@@ -11411,6 +11487,7 @@ instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (MulI src1 (LoadI src2)));
|
match(Set dst (MulI src1 (LoadI src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
ins_cost(350);
|
ins_cost(350);
|
||||||
format %{ "eimull $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eimull $dst, $src1, $src2\t# int ndd" %}
|
||||||
@@ -11462,6 +11539,7 @@ instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (MulL src1 src2));
|
match(Set dst (MulL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
ins_cost(300);
|
ins_cost(300);
|
||||||
format %{ "eimulq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eimulq $dst, $src1, $src2\t# long ndd" %}
|
||||||
@@ -11503,6 +11581,7 @@ instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (MulL src1 (LoadL src2)));
|
match(Set dst (MulL src1 (LoadL src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
ins_cost(350);
|
ins_cost(350);
|
||||||
format %{ "eimulq $dst, $src1, $src2 \t# long" %}
|
format %{ "eimulq $dst, $src1, $src2 \t# long" %}
|
||||||
@@ -11777,6 +11856,7 @@ instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (LShiftI src shift));
|
match(Set dst (LShiftI src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esall $dst, $src, $shift\t# int(ndd)" %}
|
format %{ "esall $dst, $src, $shift\t# int(ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -11805,6 +11885,7 @@ instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (LShiftI src shift));
|
match(Set dst (LShiftI src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esall $dst, $src, $shift\t# int (ndd)" %}
|
format %{ "esall $dst, $src, $shift\t# int (ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -11911,6 +11992,7 @@ instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (RShiftI src shift));
|
match(Set dst (RShiftI src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esarl $dst, $src, $shift\t# int (ndd)" %}
|
format %{ "esarl $dst, $src, $shift\t# int (ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12017,6 +12099,7 @@ instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (URShiftI src shift));
|
match(Set dst (URShiftI src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %}
|
format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12124,6 +12207,7 @@ instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (LShiftL src shift));
|
match(Set dst (LShiftL src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esalq $dst, $src, $shift\t# long (ndd)" %}
|
format %{ "esalq $dst, $src, $shift\t# long (ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12152,6 +12236,7 @@ instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (LShiftL src shift));
|
match(Set dst (LShiftL src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esalq $dst, $src, $shift\t# long (ndd)" %}
|
format %{ "esalq $dst, $src, $shift\t# long (ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12258,6 +12343,7 @@ instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (RShiftL src shift));
|
match(Set dst (RShiftL src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "esarq $dst, $src, $shift\t# long (ndd)" %}
|
format %{ "esarq $dst, $src, $shift\t# long (ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12364,6 +12450,7 @@ instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (URShiftL src shift));
|
match(Set dst (URShiftL src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %}
|
format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12535,6 +12622,7 @@ instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX && n->bottom_type()->basic_type() == T_INT);
|
predicate(UseAPX && n->bottom_type()->basic_type() == T_INT);
|
||||||
match(Set dst (RotateLeft src shift));
|
match(Set dst (RotateLeft src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %}
|
format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12599,6 +12687,7 @@ instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX && n->bottom_type()->basic_type() == T_INT);
|
predicate(UseAPX && n->bottom_type()->basic_type() == T_INT);
|
||||||
match(Set dst (RotateRight src shift));
|
match(Set dst (RotateRight src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %}
|
format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12651,6 +12740,7 @@ instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr)
|
|||||||
predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG);
|
predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG);
|
||||||
match(Set dst (RotateLeft dst shift));
|
match(Set dst (RotateLeft dst shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
|
||||||
format %{ "rolq $dst, $shift" %}
|
format %{ "rolq $dst, $shift" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
__ rolq($dst$$Register);
|
__ rolq($dst$$Register);
|
||||||
@@ -12664,6 +12754,7 @@ instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG);
|
predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG);
|
||||||
match(Set dst (RotateLeft src shift));
|
match(Set dst (RotateLeft src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %}
|
format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12728,6 +12819,7 @@ instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr)
|
|||||||
predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG);
|
predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG);
|
||||||
match(Set dst (RotateRight src shift));
|
match(Set dst (RotateRight src shift));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %}
|
format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12805,7 +12897,7 @@ instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AndI src1 src2));
|
match(Set dst (AndI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12898,7 +12990,7 @@ instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AndI src1 src2));
|
match(Set dst (AndI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -12942,7 +13034,7 @@ instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AndI src1 (LoadI src2)));
|
match(Set dst (AndI src1 (LoadI src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
|
||||||
@@ -13142,7 +13234,7 @@ instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (OrI src1 src2));
|
match(Set dst (OrI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13171,7 +13263,7 @@ instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (OrI src1 src2));
|
match(Set dst (OrI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13185,7 +13277,7 @@ instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (OrI src1 src2));
|
match(Set dst (OrI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eorl $dst, $src2, $src1\t# int ndd" %}
|
format %{ "eorl $dst, $src2, $src1\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13229,7 +13321,7 @@ instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (OrI src1 (LoadI src2)));
|
match(Set dst (OrI src1 (LoadI src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
|
||||||
@@ -13305,7 +13397,7 @@ instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (XorI src1 src2));
|
match(Set dst (XorI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13331,6 +13423,7 @@ instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm)
|
|||||||
%{
|
%{
|
||||||
match(Set dst (XorI src imm));
|
match(Set dst (XorI src imm));
|
||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "enotl $dst, $src" %}
|
format %{ "enotl $dst, $src" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13361,7 +13454,7 @@ instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1);
|
predicate(UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1);
|
||||||
match(Set dst (XorI src1 src2));
|
match(Set dst (XorI src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13407,7 +13500,7 @@ instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (XorI src1 (LoadI src2)));
|
match(Set dst (XorI src1 (LoadI src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
|
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
|
||||||
@@ -13486,7 +13579,7 @@ instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AndL src1 src2));
|
match(Set dst (AndL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13542,7 +13635,7 @@ instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AndL src1 src2));
|
match(Set dst (AndL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13586,7 +13679,7 @@ instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (AndL src1 (LoadL src2)));
|
match(Set dst (AndL src1 (LoadL src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
|
||||||
@@ -13789,7 +13882,7 @@ instruct orL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (OrL src1 src2));
|
match(Set dst (OrL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13844,7 +13937,7 @@ instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (OrL src1 src2));
|
match(Set dst (OrL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13858,7 +13951,7 @@ instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (OrL src1 src2));
|
match(Set dst (OrL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "eorq $dst, $src2, $src1\t# long ndd" %}
|
format %{ "eorq $dst, $src2, $src1\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -13903,7 +13996,7 @@ instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (OrL src1 (LoadL src2)));
|
match(Set dst (OrL src1 (LoadL src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
|
||||||
@@ -13982,7 +14075,7 @@ instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (XorL src1 src2));
|
match(Set dst (XorL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -14008,6 +14101,7 @@ instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm)
|
|||||||
%{
|
%{
|
||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (XorL src imm));
|
match(Set dst (XorL src imm));
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "enotq $dst, $src" %}
|
format %{ "enotq $dst, $src" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -14038,7 +14132,7 @@ instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr)
|
|||||||
predicate(UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L);
|
predicate(UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L);
|
||||||
match(Set dst (XorL src1 src2));
|
match(Set dst (XorL src1 src2));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
@@ -14084,7 +14178,7 @@ instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (XorL src1 (LoadL src2)));
|
match(Set dst (XorL src1 (LoadL src2)));
|
||||||
effect(KILL cr);
|
effect(KILL cr);
|
||||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag);
|
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||||
|
|
||||||
ins_cost(150);
|
ins_cost(150);
|
||||||
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
|
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
|
||||||
@@ -14492,7 +14586,7 @@ instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct convF2I_reg_reg_avx10(rRegI dst, regF src)
|
instruct convF2I_reg_reg_avx10_2(rRegI dst, regF src)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (ConvF2I src));
|
match(Set dst (ConvF2I src));
|
||||||
@@ -14503,7 +14597,7 @@ instruct convF2I_reg_reg_avx10(rRegI dst, regF src)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct convF2I_reg_mem_avx10(rRegI dst, memory src)
|
instruct convF2I_reg_mem_avx10_2(rRegI dst, memory src)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (ConvF2I (LoadF src)));
|
match(Set dst (ConvF2I (LoadF src)));
|
||||||
@@ -14526,7 +14620,7 @@ instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct convF2L_reg_reg_avx10(rRegL dst, regF src)
|
instruct convF2L_reg_reg_avx10_2(rRegL dst, regF src)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (ConvF2L src));
|
match(Set dst (ConvF2L src));
|
||||||
@@ -14537,7 +14631,7 @@ instruct convF2L_reg_reg_avx10(rRegL dst, regF src)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct convF2L_reg_mem_avx10(rRegL dst, memory src)
|
instruct convF2L_reg_mem_avx10_2(rRegL dst, memory src)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (ConvF2L (LoadF src)));
|
match(Set dst (ConvF2L (LoadF src)));
|
||||||
@@ -14560,7 +14654,7 @@ instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct convD2I_reg_reg_avx10(rRegI dst, regD src)
|
instruct convD2I_reg_reg_avx10_2(rRegI dst, regD src)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (ConvD2I src));
|
match(Set dst (ConvD2I src));
|
||||||
@@ -14571,7 +14665,7 @@ instruct convD2I_reg_reg_avx10(rRegI dst, regD src)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct convD2I_reg_mem_avx10(rRegI dst, memory src)
|
instruct convD2I_reg_mem_avx10_2(rRegI dst, memory src)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (ConvD2I (LoadD src)));
|
match(Set dst (ConvD2I (LoadD src)));
|
||||||
@@ -14594,7 +14688,7 @@ instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct convD2L_reg_reg_avx10(rRegL dst, regD src)
|
instruct convD2L_reg_reg_avx10_2(rRegL dst, regD src)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (ConvD2L src));
|
match(Set dst (ConvD2L src));
|
||||||
@@ -14605,7 +14699,7 @@ instruct convD2L_reg_reg_avx10(rRegL dst, regD src)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct convD2L_reg_mem_avx10(rRegL dst, memory src)
|
instruct convD2L_reg_mem_avx10_2(rRegL dst, memory src)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (ConvD2L (LoadD src)));
|
match(Set dst (ConvD2L (LoadD src)));
|
||||||
@@ -16539,6 +16633,7 @@ instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (MinI src1 src2));
|
match(Set dst (MinI src1 src2));
|
||||||
effect(DEF dst, USE src1, USE src2);
|
effect(DEF dst, USE src1, USE src2);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
ins_cost(200);
|
ins_cost(200);
|
||||||
expand %{
|
expand %{
|
||||||
@@ -16590,6 +16685,7 @@ instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2)
|
|||||||
predicate(UseAPX);
|
predicate(UseAPX);
|
||||||
match(Set dst (MaxI src1 src2));
|
match(Set dst (MaxI src1 src2));
|
||||||
effect(DEF dst, USE src1, USE src2);
|
effect(DEF dst, USE src1, USE src2);
|
||||||
|
flag(PD::Flag_ndd_demotable);
|
||||||
|
|
||||||
ins_cost(200);
|
ins_cost(200);
|
||||||
expand %{
|
expand %{
|
||||||
@@ -19564,7 +19660,7 @@ instruct minmax_reductionF_av(legRegF dst, legVec src, legVec tmp, legVec atmp,
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct minmax_reduction2F_avx10(regF dst, immF src1, vec src2, vec xtmp1) %{
|
instruct minmax_reduction2F_avx10_2(regF dst, immF src1, vec src2, vec xtmp1) %{
|
||||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeF::POS_INF) ||
|
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeF::POS_INF) ||
|
||||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeF::NEG_INF)) &&
|
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeF::NEG_INF)) &&
|
||||||
@@ -19582,7 +19678,7 @@ instruct minmax_reduction2F_avx10(regF dst, immF src1, vec src2, vec xtmp1) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct minmax_reductionF_avx10(regF dst, immF src1, vec src2, vec xtmp1, vec xtmp2) %{
|
instruct minmax_reductionF_avx10_2(regF dst, immF src1, vec src2, vec xtmp1, vec xtmp2) %{
|
||||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeF::POS_INF) ||
|
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeF::POS_INF) ||
|
||||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeF::NEG_INF)) &&
|
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeF::NEG_INF)) &&
|
||||||
@@ -19600,7 +19696,7 @@ instruct minmax_reductionF_avx10(regF dst, immF src1, vec src2, vec xtmp1, vec x
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct minmax_reduction2F_avx10_av(regF dst, vec src, vec xtmp1) %{
|
instruct minmax_reduction2F_av_avx10_2(regF dst, vec src, vec xtmp1) %{
|
||||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||||
Matcher::vector_length(n->in(2)) == 2);
|
Matcher::vector_length(n->in(2)) == 2);
|
||||||
match(Set dst (MinReductionV dst src));
|
match(Set dst (MinReductionV dst src));
|
||||||
@@ -19616,7 +19712,7 @@ instruct minmax_reduction2F_avx10_av(regF dst, vec src, vec xtmp1) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct minmax_reductionF_avx10_av(regF dst, vec src, vec xtmp1, vec xtmp2) %{
|
instruct minmax_reductionF_av_avx10_2(regF dst, vec src, vec xtmp1, vec xtmp2) %{
|
||||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_FLOAT &&
|
||||||
Matcher::vector_length(n->in(2)) >= 4);
|
Matcher::vector_length(n->in(2)) >= 4);
|
||||||
match(Set dst (MinReductionV dst src));
|
match(Set dst (MinReductionV dst src));
|
||||||
@@ -19714,7 +19810,7 @@ instruct minmax_reductionD_av(legRegD dst, legVec src, legVec tmp1, legVec tmp2,
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct minmax_reduction2D_avx10(regD dst, immD src1, vec src2, vec xtmp1) %{
|
instruct minmax_reduction2D_avx10_2(regD dst, immD src1, vec src2, vec xtmp1) %{
|
||||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeD::POS_INF) ||
|
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeD::POS_INF) ||
|
||||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeD::NEG_INF)) &&
|
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeD::NEG_INF)) &&
|
||||||
@@ -19732,7 +19828,7 @@ instruct minmax_reduction2D_avx10(regD dst, immD src1, vec src2, vec xtmp1) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct minmax_reductionD_avx10(regD dst, immD src1, vec src2, vec xtmp1, vec xtmp2) %{
|
instruct minmax_reductionD_avx10_2(regD dst, immD src1, vec src2, vec xtmp1, vec xtmp2) %{
|
||||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||||
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeD::POS_INF) ||
|
((n->Opcode() == Op_MinReductionV && n->in(1)->bottom_type() == TypeD::POS_INF) ||
|
||||||
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeD::NEG_INF)) &&
|
(n->Opcode() == Op_MaxReductionV && n->in(1)->bottom_type() == TypeD::NEG_INF)) &&
|
||||||
@@ -19751,7 +19847,7 @@ instruct minmax_reductionD_avx10(regD dst, immD src1, vec src2, vec xtmp1, vec x
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
instruct minmax_reduction2D_av_avx10(regD dst, vec src, vec xtmp1) %{
|
instruct minmax_reduction2D_av_avx10_2(regD dst, vec src, vec xtmp1) %{
|
||||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||||
Matcher::vector_length(n->in(2)) == 2);
|
Matcher::vector_length(n->in(2)) == 2);
|
||||||
match(Set dst (MinReductionV dst src));
|
match(Set dst (MinReductionV dst src));
|
||||||
@@ -19767,7 +19863,7 @@ instruct minmax_reduction2D_av_avx10(regD dst, vec src, vec xtmp1) %{
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct minmax_reductionD_av_avx10(regD dst, vec src, vec xtmp1, vec xtmp2) %{
|
instruct minmax_reductionD_av_avx10_2(regD dst, vec src, vec xtmp1, vec xtmp2) %{
|
||||||
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
predicate(VM_Version::supports_avx10_2() && Matcher::vector_element_basic_type(n->in(2)) == T_DOUBLE &&
|
||||||
Matcher::vector_length(n->in(2)) >= 4);
|
Matcher::vector_length(n->in(2)) >= 4);
|
||||||
match(Set dst (MinReductionV dst src));
|
match(Set dst (MinReductionV dst src));
|
||||||
@@ -20670,7 +20766,7 @@ instruct vminmaxL_reg_evex(vec dst, vec src1, vec src2) %{
|
|||||||
%}
|
%}
|
||||||
|
|
||||||
// Float/Double vector Min/Max
|
// Float/Double vector Min/Max
|
||||||
instruct minmaxFP_avx10_reg(vec dst, vec a, vec b) %{
|
instruct minmaxFP_reg_avx10_2(vec dst, vec a, vec b) %{
|
||||||
predicate(VM_Version::supports_avx10_2() &&
|
predicate(VM_Version::supports_avx10_2() &&
|
||||||
is_floating_point_type(Matcher::vector_element_basic_type(n))); // T_FLOAT, T_DOUBLE
|
is_floating_point_type(Matcher::vector_element_basic_type(n))); // T_FLOAT, T_DOUBLE
|
||||||
match(Set dst (MinV a b));
|
match(Set dst (MinV a b));
|
||||||
@@ -22017,29 +22113,29 @@ instruct castFtoX_reg_evex(vec dst, vec src, vec xtmp1, vec xtmp2, kReg ktmp1, k
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct castFtoX_reg_avx10(vec dst, vec src) %{
|
instruct castFtoX_reg_avx10_2(vec dst, vec src) %{
|
||||||
predicate(VM_Version::supports_avx10_2() &&
|
predicate(VM_Version::supports_avx10_2() &&
|
||||||
is_integral_type(Matcher::vector_element_basic_type(n)));
|
is_integral_type(Matcher::vector_element_basic_type(n)));
|
||||||
match(Set dst (VectorCastF2X src));
|
match(Set dst (VectorCastF2X src));
|
||||||
format %{ "vector_cast_f2x_avx10 $dst, $src\t!" %}
|
format %{ "vector_cast_f2x_avx10_2 $dst, $src\t!" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
|
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
|
||||||
int vlen_enc = (to_elem_bt == T_LONG) ? vector_length_encoding(this) : vector_length_encoding(this, $src);
|
int vlen_enc = (to_elem_bt == T_LONG) ? vector_length_encoding(this) : vector_length_encoding(this, $src);
|
||||||
__ vector_castF2X_avx10(to_elem_bt, $dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
|
__ vector_castF2X_avx10_2(to_elem_bt, $dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct castFtoX_mem_avx10(vec dst, memory src) %{
|
instruct castFtoX_mem_avx10_2(vec dst, memory src) %{
|
||||||
predicate(VM_Version::supports_avx10_2() &&
|
predicate(VM_Version::supports_avx10_2() &&
|
||||||
is_integral_type(Matcher::vector_element_basic_type(n)));
|
is_integral_type(Matcher::vector_element_basic_type(n)));
|
||||||
match(Set dst (VectorCastF2X (LoadVector src)));
|
match(Set dst (VectorCastF2X (LoadVector src)));
|
||||||
format %{ "vector_cast_f2x_avx10 $dst, $src\t!" %}
|
format %{ "vector_cast_f2x_avx10_2 $dst, $src\t!" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
int vlen = Matcher::vector_length(this);
|
int vlen = Matcher::vector_length(this);
|
||||||
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
|
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
|
||||||
int vlen_enc = (to_elem_bt == T_LONG) ? vector_length_encoding(this) : vector_length_encoding(vlen * sizeof(jfloat));
|
int vlen_enc = (to_elem_bt == T_LONG) ? vector_length_encoding(this) : vector_length_encoding(vlen * sizeof(jfloat));
|
||||||
__ vector_castF2X_avx10(to_elem_bt, $dst$$XMMRegister, $src$$Address, vlen_enc);
|
__ vector_castF2X_avx10_2(to_elem_bt, $dst$$XMMRegister, $src$$Address, vlen_enc);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
@@ -22091,29 +22187,29 @@ instruct castDtoX_reg_evex(vec dst, vec src, vec xtmp1, vec xtmp2, kReg ktmp1, k
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct castDtoX_reg_avx10(vec dst, vec src) %{
|
instruct castDtoX_reg_avx10_2(vec dst, vec src) %{
|
||||||
predicate(VM_Version::supports_avx10_2() &&
|
predicate(VM_Version::supports_avx10_2() &&
|
||||||
is_integral_type(Matcher::vector_element_basic_type(n)));
|
is_integral_type(Matcher::vector_element_basic_type(n)));
|
||||||
match(Set dst (VectorCastD2X src));
|
match(Set dst (VectorCastD2X src));
|
||||||
format %{ "vector_cast_d2x_avx10 $dst, $src\t!" %}
|
format %{ "vector_cast_d2x_avx10_2 $dst, $src\t!" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
int vlen_enc = vector_length_encoding(this, $src);
|
int vlen_enc = vector_length_encoding(this, $src);
|
||||||
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
|
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
|
||||||
__ vector_castD2X_avx10(to_elem_bt, $dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
|
__ vector_castD2X_avx10_2(to_elem_bt, $dst$$XMMRegister, $src$$XMMRegister, vlen_enc);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct castDtoX_mem_avx10(vec dst, memory src) %{
|
instruct castDtoX_mem_avx10_2(vec dst, memory src) %{
|
||||||
predicate(VM_Version::supports_avx10_2() &&
|
predicate(VM_Version::supports_avx10_2() &&
|
||||||
is_integral_type(Matcher::vector_element_basic_type(n)));
|
is_integral_type(Matcher::vector_element_basic_type(n)));
|
||||||
match(Set dst (VectorCastD2X (LoadVector src)));
|
match(Set dst (VectorCastD2X (LoadVector src)));
|
||||||
format %{ "vector_cast_d2x_avx10 $dst, $src\t!" %}
|
format %{ "vector_cast_d2x_avx10_2 $dst, $src\t!" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
int vlen = Matcher::vector_length(this);
|
int vlen = Matcher::vector_length(this);
|
||||||
int vlen_enc = vector_length_encoding(vlen * sizeof(jdouble));
|
int vlen_enc = vector_length_encoding(vlen * sizeof(jdouble));
|
||||||
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
|
BasicType to_elem_bt = Matcher::vector_element_basic_type(this);
|
||||||
__ vector_castD2X_avx10(to_elem_bt, $dst$$XMMRegister, $src$$Address, vlen_enc);
|
__ vector_castD2X_avx10_2(to_elem_bt, $dst$$XMMRegister, $src$$Address, vlen_enc);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
@@ -25085,14 +25181,14 @@ instruct scalar_binOps_HF_reg(regF dst, regF src1, regF src2)
|
|||||||
ins_pipe(pipe_slow);
|
ins_pipe(pipe_slow);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct scalar_minmax_HF_avx10_reg(regF dst, regF src1, regF src2)
|
instruct scalar_minmax_HF_reg_avx10_2(regF dst, regF src1, regF src2)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (MaxHF src1 src2));
|
match(Set dst (MaxHF src1 src2));
|
||||||
match(Set dst (MinHF src1 src2));
|
match(Set dst (MinHF src1 src2));
|
||||||
format %{ "scalar_min_max_fp16 $dst, $src1, $src2" %}
|
format %{ "scalar_min_max_fp16 $dst, $src1, $src2" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
int function = this->ideal_Opcode() == Op_MinHF ? AVX10_MINMAX_MIN_COMPARE_SIGN : AVX10_MINMAX_MAX_COMPARE_SIGN;
|
int function = this->ideal_Opcode() == Op_MinHF ? AVX10_2_MINMAX_MIN_COMPARE_SIGN : AVX10_2_MINMAX_MAX_COMPARE_SIGN;
|
||||||
__ eminmaxsh($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, function);
|
__ eminmaxsh($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, function);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
@@ -25200,7 +25296,7 @@ instruct vector_fma_HF_mem(vec dst, memory src1, vec src2)
|
|||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vector_minmax_HF_avx10_mem(vec dst, vec src1, memory src2)
|
instruct vector_minmax_HF_mem_avx10_2(vec dst, vec src1, memory src2)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (MinVHF src1 (VectorReinterpret (LoadVector src2))));
|
match(Set dst (MinVHF src1 (VectorReinterpret (LoadVector src2))));
|
||||||
@@ -25208,13 +25304,13 @@ instruct vector_minmax_HF_avx10_mem(vec dst, vec src1, memory src2)
|
|||||||
format %{ "vector_min_max_fp16_mem $dst, $src1, $src2" %}
|
format %{ "vector_min_max_fp16_mem $dst, $src1, $src2" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
int vlen_enc = vector_length_encoding(this);
|
int vlen_enc = vector_length_encoding(this);
|
||||||
int function = this->ideal_Opcode() == Op_MinVHF ? AVX10_MINMAX_MIN_COMPARE_SIGN : AVX10_MINMAX_MAX_COMPARE_SIGN;
|
int function = this->ideal_Opcode() == Op_MinVHF ? AVX10_2_MINMAX_MIN_COMPARE_SIGN : AVX10_2_MINMAX_MAX_COMPARE_SIGN;
|
||||||
__ evminmaxph($dst$$XMMRegister, k0, $src1$$XMMRegister, $src2$$Address, true, function, vlen_enc);
|
__ evminmaxph($dst$$XMMRegister, k0, $src1$$XMMRegister, $src2$$Address, true, function, vlen_enc);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vector_minmax_HF_avx10_reg(vec dst, vec src1, vec src2)
|
instruct vector_minmax_HF_reg_avx10_2(vec dst, vec src1, vec src2)
|
||||||
%{
|
%{
|
||||||
predicate(VM_Version::supports_avx10_2());
|
predicate(VM_Version::supports_avx10_2());
|
||||||
match(Set dst (MinVHF src1 src2));
|
match(Set dst (MinVHF src1 src2));
|
||||||
@@ -25222,7 +25318,7 @@ instruct vector_minmax_HF_avx10_reg(vec dst, vec src1, vec src2)
|
|||||||
format %{ "vector_min_max_fp16 $dst, $src1, $src2" %}
|
format %{ "vector_min_max_fp16 $dst, $src1, $src2" %}
|
||||||
ins_encode %{
|
ins_encode %{
|
||||||
int vlen_enc = vector_length_encoding(this);
|
int vlen_enc = vector_length_encoding(this);
|
||||||
int function = this->ideal_Opcode() == Op_MinVHF ? AVX10_MINMAX_MIN_COMPARE_SIGN : AVX10_MINMAX_MAX_COMPARE_SIGN;
|
int function = this->ideal_Opcode() == Op_MinVHF ? AVX10_2_MINMAX_MIN_COMPARE_SIGN : AVX10_2_MINMAX_MAX_COMPARE_SIGN;
|
||||||
__ evminmaxph($dst$$XMMRegister, k0, $src1$$XMMRegister, $src2$$XMMRegister, true, function, vlen_enc);
|
__ evminmaxph($dst$$XMMRegister, k0, $src1$$XMMRegister, $src2$$XMMRegister, true, function, vlen_enc);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
|
|||||||
@@ -1038,6 +1038,8 @@ static void* dll_load_library(const char *filename, int *eno, char *ebuf, int eb
|
|||||||
dflags |= RTLD_MEMBER;
|
dflags |= RTLD_MEMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Events::log_dll_message(nullptr, "Attempting to load shared library %s", filename);
|
||||||
|
|
||||||
void* result;
|
void* result;
|
||||||
const char* error_report = nullptr;
|
const char* error_report = nullptr;
|
||||||
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
||||||
@@ -2331,8 +2333,8 @@ int os::open(const char *path, int oflag, int mode) {
|
|||||||
|
|
||||||
if (ret != -1) {
|
if (ret != -1) {
|
||||||
if ((st_mode & S_IFMT) == S_IFDIR) {
|
if ((st_mode & S_IFMT) == S_IFDIR) {
|
||||||
errno = EISDIR;
|
|
||||||
::close(fd);
|
::close(fd);
|
||||||
|
errno = EISDIR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -861,6 +861,90 @@ pid_t os::Bsd::gettid() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the uid of a process or -1 on error.
|
||||||
|
uid_t os::Bsd::get_process_uid(pid_t pid) {
|
||||||
|
struct kinfo_proc kp;
|
||||||
|
size_t size = sizeof kp;
|
||||||
|
int mib_kern[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
|
||||||
|
if (sysctl(mib_kern, 4, &kp, &size, nullptr, 0) == 0) {
|
||||||
|
if (size > 0 && kp.kp_proc.p_pid == pid) {
|
||||||
|
return kp.kp_eproc.e_ucred.cr_uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (uid_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the process is running as root.
|
||||||
|
bool os::Bsd::is_process_root(pid_t pid) {
|
||||||
|
uid_t uid = get_process_uid(pid);
|
||||||
|
return (uid != (uid_t)-1) ? os::Posix::is_root(uid) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
// macOS has a secure per-user temporary directory.
|
||||||
|
// Root can attach to a non-root process, hence it needs
|
||||||
|
// to lookup /var/folders for the user specific temporary directory
|
||||||
|
// of the form /var/folders/*/*/T, that contains PERFDATA_NAME_user
|
||||||
|
// directory.
|
||||||
|
static const char VAR_FOLDERS[] = "/var/folders/";
|
||||||
|
int os::Bsd::get_user_tmp_dir_macos(const char* user, int vmid, char* output_path, int output_size) {
|
||||||
|
|
||||||
|
// read the var/folders directory
|
||||||
|
DIR* varfolders_dir = os::opendir(VAR_FOLDERS);
|
||||||
|
if (varfolders_dir != nullptr) {
|
||||||
|
|
||||||
|
// var/folders directory contains 2-characters subdirectories (buckets)
|
||||||
|
struct dirent* bucket_de;
|
||||||
|
|
||||||
|
// loop until the PERFDATA_NAME_user directory has been found
|
||||||
|
while ((bucket_de = os::readdir(varfolders_dir)) != nullptr) {
|
||||||
|
// skip over files and special "." and ".."
|
||||||
|
if (bucket_de->d_type != DT_DIR || bucket_de->d_name[0] == '.') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// absolute path to the bucket
|
||||||
|
char bucket[PATH_MAX];
|
||||||
|
int b = os::snprintf(bucket, PATH_MAX, "%s%s/", VAR_FOLDERS, bucket_de->d_name);
|
||||||
|
|
||||||
|
// the total length of the absolute path must not exceed the buffer size
|
||||||
|
if (b >= PATH_MAX || b < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// each bucket contains next level subdirectories
|
||||||
|
DIR* bucket_dir = os::opendir(bucket);
|
||||||
|
if (bucket_dir == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// read each subdirectory, skipping over regular files
|
||||||
|
struct dirent* subbucket_de;
|
||||||
|
while ((subbucket_de = os::readdir(bucket_dir)) != nullptr) {
|
||||||
|
if (subbucket_de->d_type != DT_DIR || subbucket_de->d_name[0] == '.') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// If the PERFDATA_NAME_user directory exists in the T subdirectory,
|
||||||
|
// this means the subdirectory is the temporary directory of the user.
|
||||||
|
char perfdata_path[PATH_MAX];
|
||||||
|
int p = os::snprintf(perfdata_path, PATH_MAX, "%s%s/T/%s_%s/", bucket, subbucket_de->d_name, PERFDATA_NAME, user);
|
||||||
|
|
||||||
|
// the total length must not exceed the output buffer size
|
||||||
|
if (p >= PATH_MAX || p < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// check if the subdirectory exists
|
||||||
|
if (os::file_exists(perfdata_path)) {
|
||||||
|
// the return value of snprintf is not checked for the second time
|
||||||
|
return os::snprintf(output_path, output_size, "%s%s/T", bucket, subbucket_de->d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os::closedir(bucket_dir);
|
||||||
|
}
|
||||||
|
os::closedir(varfolders_dir);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
intx os::current_thread_id() {
|
intx os::current_thread_id() {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
return (intx)os::Bsd::gettid();
|
return (intx)os::Bsd::gettid();
|
||||||
@@ -1035,6 +1119,8 @@ void *os::Bsd::dlopen_helper(const char *filename, int mode, char *ebuf, int ebu
|
|||||||
int rtn = fegetenv(&default_fenv);
|
int rtn = fegetenv(&default_fenv);
|
||||||
assert(rtn == 0, "fegetenv must succeed");
|
assert(rtn == 0, "fegetenv must succeed");
|
||||||
|
|
||||||
|
Events::log_dll_message(nullptr, "Attempting to load shared library %s", filename);
|
||||||
|
|
||||||
void* result;
|
void* result;
|
||||||
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
||||||
result = ::dlopen(filename, RTLD_LAZY);
|
result = ::dlopen(filename, RTLD_LAZY);
|
||||||
@@ -2275,8 +2361,8 @@ int os::open(const char *path, int oflag, int mode) {
|
|||||||
|
|
||||||
if (ret != -1) {
|
if (ret != -1) {
|
||||||
if ((st_mode & S_IFMT) == S_IFDIR) {
|
if ((st_mode & S_IFMT) == S_IFDIR) {
|
||||||
errno = EISDIR;
|
|
||||||
::close(fd);
|
::close(fd);
|
||||||
|
errno = EISDIR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@@ -61,6 +61,12 @@ class os::Bsd {
|
|||||||
static pthread_t main_thread(void) { return _main_thread; }
|
static pthread_t main_thread(void) { return _main_thread; }
|
||||||
|
|
||||||
static pid_t gettid();
|
static pid_t gettid();
|
||||||
|
static uid_t get_process_uid(pid_t pid);
|
||||||
|
static bool is_process_root(pid_t pid);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static int get_user_tmp_dir_macos(const char* user, int vmid, char* output_buffer, int buffer_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
static intptr_t* ucontext_get_sp(const ucontext_t* uc);
|
static intptr_t* ucontext_get_sp(const ucontext_t* uc);
|
||||||
static intptr_t* ucontext_get_fp(const ucontext_t* uc);
|
static intptr_t* ucontext_get_fp(const ucontext_t* uc);
|
||||||
|
|||||||
@@ -467,9 +467,9 @@ void CgroupV1MemoryController::print_version_specific_info(outputStream* st, phy
|
|||||||
kmem_max_usage.set_value(temp);
|
kmem_max_usage.set_value(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
OSContainer::print_container_helper(st, kmem_limit, "kernel_memory_limit_in_bytes");
|
OSContainer::print_container_helper(st, kmem_limit, "kernel_memory_limit");
|
||||||
OSContainer::print_container_helper(st, kmem_usage, "kernel_memory_usage_in_bytes");
|
OSContainer::print_container_helper(st, kmem_usage, "kernel_memory_usage");
|
||||||
OSContainer::print_container_helper(st, kmem_max_usage, "kernel_memory_max_usage_in_bytes");
|
OSContainer::print_container_helper(st, kmem_max_usage, "kernel_memory_max_usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
char* CgroupV1Subsystem::cpu_cpuset_cpus() {
|
char* CgroupV1Subsystem::cpu_cpuset_cpus() {
|
||||||
|
|||||||
@@ -378,8 +378,8 @@ void CgroupV2MemoryController::print_version_specific_info(outputStream* st, phy
|
|||||||
if (memory_swap_limit_value(reader(), swap_limit_val)) {
|
if (memory_swap_limit_value(reader(), swap_limit_val)) {
|
||||||
swap_limit.set_value(swap_limit_val);
|
swap_limit.set_value(swap_limit_val);
|
||||||
}
|
}
|
||||||
OSContainer::print_container_helper(st, swap_current, "memory_swap_current_in_bytes");
|
OSContainer::print_container_helper(st, swap_current, "memory_swap_current");
|
||||||
OSContainer::print_container_helper(st, swap_limit, "memory_swap_max_limit_in_bytes");
|
OSContainer::print_container_helper(st, swap_limit, "memory_swap_max_limit");
|
||||||
}
|
}
|
||||||
|
|
||||||
char* CgroupV2Controller::construct_path(char* mount_path, const char* cgroup_path) {
|
char* CgroupV2Controller::construct_path(char* mount_path, const char* cgroup_path) {
|
||||||
|
|||||||
@@ -287,20 +287,44 @@ bool OSContainer::pids_current(uint64_t& value) {
|
|||||||
return cgroup_subsystem->pids_current(value);
|
return cgroup_subsystem->pids_current(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> struct metric_fmt;
|
||||||
|
template<> struct metric_fmt<unsigned long long int> { static constexpr const char* fmt = "%llu"; };
|
||||||
|
template<> struct metric_fmt<unsigned long int> { static constexpr const char* fmt = "%lu"; };
|
||||||
|
template<> struct metric_fmt<int> { static constexpr const char* fmt = "%d"; };
|
||||||
|
template<> struct metric_fmt<const char*> { static constexpr const char* fmt = "%s"; };
|
||||||
|
|
||||||
|
template void OSContainer::print_container_metric<unsigned long long int>(outputStream*, const char*, unsigned long long int, const char*);
|
||||||
|
template void OSContainer::print_container_metric<unsigned long int>(outputStream*, const char*, unsigned long int, const char*);
|
||||||
|
template void OSContainer::print_container_metric<int>(outputStream*, const char*, int, const char*);
|
||||||
|
template void OSContainer::print_container_metric<const char*>(outputStream*, const char*, const char*, const char*);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void OSContainer::print_container_metric(outputStream* st, const char* metrics, T value, const char* unit) {
|
||||||
|
constexpr int max_length = 38; // Longest "metric: value" string ("maximum number of tasks: not supported")
|
||||||
|
constexpr int longest_value = max_length - 11; // Max length - shortest "metric: " string ("cpu_quota: ")
|
||||||
|
char value_str[longest_value + 1] = {};
|
||||||
|
os::snprintf_checked(value_str, longest_value, metric_fmt<T>::fmt, value);
|
||||||
|
st->print("%s: %*s", metrics, max_length - static_cast<int>(strlen(metrics)) - 2, value_str); // -2 for the ": "
|
||||||
|
if (unit[0] != '\0') {
|
||||||
|
st->print_cr(" %s", unit);
|
||||||
|
} else {
|
||||||
|
st->print_cr("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OSContainer::print_container_helper(outputStream* st, MetricResult& res, const char* metrics) {
|
void OSContainer::print_container_helper(outputStream* st, MetricResult& res, const char* metrics) {
|
||||||
st->print("%s: ", metrics);
|
|
||||||
if (res.success()) {
|
if (res.success()) {
|
||||||
if (res.value() != value_unlimited) {
|
if (res.value() != value_unlimited) {
|
||||||
if (res.value() >= 1024) {
|
if (res.value() >= 1024) {
|
||||||
st->print_cr(PHYS_MEM_TYPE_FORMAT " k", (physical_memory_size_type)(res.value() / K));
|
print_container_metric(st, metrics, res.value() / K, "kB");
|
||||||
} else {
|
} else {
|
||||||
st->print_cr(PHYS_MEM_TYPE_FORMAT, res.value());
|
print_container_metric(st, metrics, res.value(), "B");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
st->print_cr("%s", "unlimited");
|
print_container_metric(st, metrics, "unlimited");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not supported
|
// Not supported
|
||||||
st->print_cr("%s", "unavailable");
|
print_container_metric(st, metrics, "unavailable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ class OSContainer: AllStatic {
|
|||||||
static void init();
|
static void init();
|
||||||
static void print_version_specific_info(outputStream* st);
|
static void print_version_specific_info(outputStream* st);
|
||||||
static void print_container_helper(outputStream* st, MetricResult& res, const char* metrics);
|
static void print_container_helper(outputStream* st, MetricResult& res, const char* metrics);
|
||||||
|
template <typename T>
|
||||||
|
static void print_container_metric(outputStream* st, const char* metrics, T value, const char* unit = "");
|
||||||
|
|
||||||
static inline bool is_containerized();
|
static inline bool is_containerized();
|
||||||
static const char * container_type();
|
static const char * container_type();
|
||||||
|
|||||||
@@ -159,9 +159,7 @@ physical_memory_size_type os::Linux::_physical_memory = 0;
|
|||||||
address os::Linux::_initial_thread_stack_bottom = nullptr;
|
address os::Linux::_initial_thread_stack_bottom = nullptr;
|
||||||
uintptr_t os::Linux::_initial_thread_stack_size = 0;
|
uintptr_t os::Linux::_initial_thread_stack_size = 0;
|
||||||
|
|
||||||
int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = nullptr;
|
|
||||||
pthread_t os::Linux::_main_thread;
|
pthread_t os::Linux::_main_thread;
|
||||||
bool os::Linux::_supports_fast_thread_cpu_time = false;
|
|
||||||
const char * os::Linux::_libc_version = nullptr;
|
const char * os::Linux::_libc_version = nullptr;
|
||||||
const char * os::Linux::_libpthread_version = nullptr;
|
const char * os::Linux::_libpthread_version = nullptr;
|
||||||
|
|
||||||
@@ -1475,29 +1473,6 @@ void os::Linux::capture_initial_stack(size_t max_size) {
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// time support
|
// time support
|
||||||
|
|
||||||
void os::Linux::fast_thread_clock_init() {
|
|
||||||
clockid_t clockid;
|
|
||||||
struct timespec tp;
|
|
||||||
int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) =
|
|
||||||
(int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
|
|
||||||
|
|
||||||
// Switch to using fast clocks for thread cpu time if
|
|
||||||
// the clock_getres() returns 0 error code.
|
|
||||||
// Note, that some kernels may support the current thread
|
|
||||||
// clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks
|
|
||||||
// returned by the pthread_getcpuclockid().
|
|
||||||
// If the fast POSIX clocks are supported then the clock_getres()
|
|
||||||
// must return at least tp.tv_sec == 0 which means a resolution
|
|
||||||
// better than 1 sec. This is extra check for reliability.
|
|
||||||
|
|
||||||
if (pthread_getcpuclockid_func &&
|
|
||||||
pthread_getcpuclockid_func(_main_thread, &clockid) == 0 &&
|
|
||||||
clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
|
|
||||||
_supports_fast_thread_cpu_time = true;
|
|
||||||
_pthread_getcpuclockid = pthread_getcpuclockid_func;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// thread_id is kernel thread id (similar to Solaris LWP id)
|
// thread_id is kernel thread id (similar to Solaris LWP id)
|
||||||
intx os::current_thread_id() { return os::Linux::gettid(); }
|
intx os::current_thread_id() { return os::Linux::gettid(); }
|
||||||
int os::current_process_id() {
|
int os::current_process_id() {
|
||||||
@@ -1900,6 +1875,8 @@ void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) {
|
|||||||
assert(rtn == 0, "fegetenv must succeed");
|
assert(rtn == 0, "fegetenv must succeed");
|
||||||
#endif // IA32
|
#endif // IA32
|
||||||
|
|
||||||
|
Events::log_dll_message(nullptr, "Attempting to load shared library %s", filename);
|
||||||
|
|
||||||
void* result;
|
void* result;
|
||||||
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
JFR_ONLY(NativeLibraryLoadEvent load_event(filename, &result);)
|
||||||
result = ::dlopen(filename, RTLD_LAZY);
|
result = ::dlopen(filename, RTLD_LAZY);
|
||||||
@@ -2455,62 +2432,57 @@ bool os::Linux::print_container_info(outputStream* st) {
|
|||||||
st->print_cr("container (cgroup) information:");
|
st->print_cr("container (cgroup) information:");
|
||||||
|
|
||||||
const char *p_ct = OSContainer::container_type();
|
const char *p_ct = OSContainer::container_type();
|
||||||
st->print_cr("container_type: %s", p_ct != nullptr ? p_ct : "not supported");
|
OSContainer::print_container_metric(st, "container_type", p_ct != nullptr ? p_ct : "not supported");
|
||||||
|
|
||||||
char *p = OSContainer::cpu_cpuset_cpus();
|
char *p = OSContainer::cpu_cpuset_cpus();
|
||||||
st->print_cr("cpu_cpuset_cpus: %s", p != nullptr ? p : "not supported");
|
OSContainer::print_container_metric(st, "cpu_cpuset_cpus", p != nullptr ? p : "not supported");
|
||||||
free(p);
|
free(p);
|
||||||
|
|
||||||
p = OSContainer::cpu_cpuset_memory_nodes();
|
p = OSContainer::cpu_cpuset_memory_nodes();
|
||||||
st->print_cr("cpu_memory_nodes: %s", p != nullptr ? p : "not supported");
|
OSContainer::print_container_metric(st, "cpu_memory_nodes", p != nullptr ? p : "not supported");
|
||||||
free(p);
|
free(p);
|
||||||
|
|
||||||
int i = -1;
|
int i = -1;
|
||||||
bool supported = OSContainer::active_processor_count(i);
|
bool supported = OSContainer::active_processor_count(i);
|
||||||
st->print("active_processor_count: ");
|
|
||||||
if (supported) {
|
if (supported) {
|
||||||
assert(i > 0, "must be");
|
assert(i > 0, "must be");
|
||||||
if (ActiveProcessorCount > 0) {
|
if (ActiveProcessorCount > 0) {
|
||||||
st->print_cr("%d, but overridden by -XX:ActiveProcessorCount %d", i, ActiveProcessorCount);
|
OSContainer::print_container_metric(st, "active_processor_count", ActiveProcessorCount, "(from -XX:ActiveProcessorCount)");
|
||||||
} else {
|
} else {
|
||||||
st->print_cr("%d", i);
|
OSContainer::print_container_metric(st, "active_processor_count", i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
st->print_cr("not supported");
|
OSContainer::print_container_metric(st, "active_processor_count", "not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
supported = OSContainer::cpu_quota(i);
|
supported = OSContainer::cpu_quota(i);
|
||||||
st->print("cpu_quota: ");
|
|
||||||
if (supported && i > 0) {
|
if (supported && i > 0) {
|
||||||
st->print_cr("%d", i);
|
OSContainer::print_container_metric(st, "cpu_quota", i);
|
||||||
} else {
|
} else {
|
||||||
st->print_cr("%s", !supported ? "not supported" : "no quota");
|
OSContainer::print_container_metric(st, "cpu_quota", !supported ? "not supported" : "no quota");
|
||||||
}
|
}
|
||||||
|
|
||||||
supported = OSContainer::cpu_period(i);
|
supported = OSContainer::cpu_period(i);
|
||||||
st->print("cpu_period: ");
|
|
||||||
if (supported && i > 0) {
|
if (supported && i > 0) {
|
||||||
st->print_cr("%d", i);
|
OSContainer::print_container_metric(st, "cpu_period", i);
|
||||||
} else {
|
} else {
|
||||||
st->print_cr("%s", !supported ? "not supported" : "no period");
|
OSContainer::print_container_metric(st, "cpu_period", !supported ? "not supported" : "no period");
|
||||||
}
|
}
|
||||||
|
|
||||||
supported = OSContainer::cpu_shares(i);
|
supported = OSContainer::cpu_shares(i);
|
||||||
st->print("cpu_shares: ");
|
|
||||||
if (supported && i > 0) {
|
if (supported && i > 0) {
|
||||||
st->print_cr("%d", i);
|
OSContainer::print_container_metric(st, "cpu_shares", i);
|
||||||
} else {
|
} else {
|
||||||
st->print_cr("%s", !supported ? "not supported" : "no shares");
|
OSContainer::print_container_metric(st, "cpu_shares", !supported ? "not supported" : "no shares");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t j = 0;
|
uint64_t j = 0;
|
||||||
supported = OSContainer::cpu_usage_in_micros(j);
|
supported = OSContainer::cpu_usage_in_micros(j);
|
||||||
st->print("cpu_usage_in_micros: ");
|
|
||||||
if (supported && j > 0) {
|
if (supported && j > 0) {
|
||||||
st->print_cr(UINT64_FORMAT, j);
|
OSContainer::print_container_metric(st, "cpu_usage", j, "us");
|
||||||
} else {
|
} else {
|
||||||
st->print_cr("%s", !supported ? "not supported" : "no usage");
|
OSContainer::print_container_metric(st, "cpu_usage", !supported ? "not supported" : "no usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
MetricResult memory_limit;
|
MetricResult memory_limit;
|
||||||
@@ -2553,31 +2525,29 @@ bool os::Linux::print_container_info(outputStream* st) {
|
|||||||
if (OSContainer::cache_usage_in_bytes(val)) {
|
if (OSContainer::cache_usage_in_bytes(val)) {
|
||||||
cache_usage.set_value(val);
|
cache_usage.set_value(val);
|
||||||
}
|
}
|
||||||
OSContainer::print_container_helper(st, memory_limit, "memory_limit_in_bytes");
|
OSContainer::print_container_helper(st, memory_limit, "memory_limit");
|
||||||
OSContainer::print_container_helper(st, mem_swap_limit, "memory_and_swap_limit_in_bytes");
|
OSContainer::print_container_helper(st, mem_swap_limit, "memory_and_swap_limit");
|
||||||
OSContainer::print_container_helper(st, mem_soft_limit, "memory_soft_limit_in_bytes");
|
OSContainer::print_container_helper(st, mem_soft_limit, "memory_soft_limit");
|
||||||
OSContainer::print_container_helper(st, mem_throttle_limit, "memory_throttle_limit_in_bytes");
|
OSContainer::print_container_helper(st, mem_throttle_limit, "memory_throttle_limit");
|
||||||
OSContainer::print_container_helper(st, mem_usage, "memory_usage_in_bytes");
|
OSContainer::print_container_helper(st, mem_usage, "memory_usage");
|
||||||
OSContainer::print_container_helper(st, mem_max_usage, "memory_max_usage_in_bytes");
|
OSContainer::print_container_helper(st, mem_max_usage, "memory_max_usage");
|
||||||
OSContainer::print_container_helper(st, rss_usage, "rss_usage_in_bytes");
|
OSContainer::print_container_helper(st, rss_usage, "rss_usage");
|
||||||
OSContainer::print_container_helper(st, cache_usage, "cache_usage_in_bytes");
|
OSContainer::print_container_helper(st, cache_usage, "cache_usage");
|
||||||
|
|
||||||
OSContainer::print_version_specific_info(st);
|
OSContainer::print_version_specific_info(st);
|
||||||
|
|
||||||
supported = OSContainer::pids_max(j);
|
supported = OSContainer::pids_max(j);
|
||||||
st->print("maximum number of tasks: ");
|
|
||||||
if (supported && j != value_unlimited) {
|
if (supported && j != value_unlimited) {
|
||||||
st->print_cr(UINT64_FORMAT, j);
|
OSContainer::print_container_metric(st, "maximum number of tasks", j);
|
||||||
} else {
|
} else {
|
||||||
st->print_cr("%s", !supported ? "not supported" : "unlimited");
|
OSContainer::print_container_metric(st, "maximum number of tasks", !supported ? "not supported" : "unlimited");
|
||||||
}
|
}
|
||||||
|
|
||||||
supported = OSContainer::pids_current(j);
|
supported = OSContainer::pids_current(j);
|
||||||
st->print("current number of tasks: ");
|
|
||||||
if (supported && j > 0) {
|
if (supported && j > 0) {
|
||||||
st->print_cr(UINT64_FORMAT, j);
|
OSContainer::print_container_metric(st, "current number of tasks", j);
|
||||||
} else {
|
} else {
|
||||||
st->print_cr("%s", !supported ? "not supported" : "no current tasks");
|
OSContainer::print_container_metric(st, "current number of tasks", !supported ? "not supported" : "no tasks");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -4321,14 +4291,7 @@ OSReturn os::get_native_priority(const Thread* const thread,
|
|||||||
return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);
|
return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the fastest way to get thread cpu time on Linux.
|
jlong os::Linux::thread_cpu_time(clockid_t clockid) {
|
||||||
// Returns cpu time (user+sys) for any thread, not only for current.
|
|
||||||
// POSIX compliant clocks are implemented in the kernels 2.6.16+.
|
|
||||||
// It might work on 2.6.10+ with a special kernel/glibc patch.
|
|
||||||
// For reference, please, see IEEE Std 1003.1-2004:
|
|
||||||
// http://www.unix.org/single_unix_specification
|
|
||||||
|
|
||||||
jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
|
|
||||||
struct timespec tp;
|
struct timespec tp;
|
||||||
int status = clock_gettime(clockid, &tp);
|
int status = clock_gettime(clockid, &tp);
|
||||||
assert(status == 0, "clock_gettime error: %s", os::strerror(errno));
|
assert(status == 0, "clock_gettime error: %s", os::strerror(errno));
|
||||||
@@ -4556,8 +4519,6 @@ jint os::init_2(void) {
|
|||||||
|
|
||||||
os::Posix::init_2();
|
os::Posix::init_2();
|
||||||
|
|
||||||
Linux::fast_thread_clock_init();
|
|
||||||
|
|
||||||
if (PosixSignals::init() == JNI_ERR) {
|
if (PosixSignals::init() == JNI_ERR) {
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
}
|
}
|
||||||
@@ -4957,8 +4918,8 @@ int os::open(const char *path, int oflag, int mode) {
|
|||||||
|
|
||||||
if (ret != -1) {
|
if (ret != -1) {
|
||||||
if ((st_mode & S_IFMT) == S_IFDIR) {
|
if ((st_mode & S_IFMT) == S_IFDIR) {
|
||||||
errno = EISDIR;
|
|
||||||
::close(fd);
|
::close(fd);
|
||||||
|
errno = EISDIR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -4985,20 +4946,42 @@ int os::open(const char *path, int oflag, int mode) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time);
|
// Since kernel v2.6.12 the Linux ABI has had support for encoding the clock
|
||||||
|
// types in the last three bits. Bit 2 indicates whether a cpu clock refers to a
|
||||||
|
// thread or a process. Bits 1 and 0 give the type: PROF=0, VIRT=1, SCHED=2, or
|
||||||
|
// FD=3. The clock CPUCLOCK_VIRT (0b001) reports the thread's consumed user
|
||||||
|
// time. POSIX compliant implementations of pthread_getcpuclockid return the
|
||||||
|
// clock CPUCLOCK_SCHED (0b010) which reports the thread's consumed system+user
|
||||||
|
// time (as mandated by the POSIX standard POSIX.1-2024/IEEE Std 1003.1-2024
|
||||||
|
// §3.90).
|
||||||
|
static bool get_thread_clockid(Thread* thread, clockid_t* clockid, bool total) {
|
||||||
|
constexpr clockid_t CLOCK_TYPE_MASK = 3;
|
||||||
|
constexpr clockid_t CPUCLOCK_VIRT = 1;
|
||||||
|
|
||||||
static jlong fast_cpu_time(Thread *thread) {
|
int rc = pthread_getcpuclockid(thread->osthread()->pthread_id(), clockid);
|
||||||
clockid_t clockid;
|
if (rc != 0) {
|
||||||
int rc = os::Linux::pthread_getcpuclockid(thread->osthread()->pthread_id(),
|
// It's possible to encounter a terminated native thread that failed
|
||||||
&clockid);
|
// to detach itself from the VM - which should result in ESRCH.
|
||||||
if (rc == 0) {
|
assert_status(rc == ESRCH, rc, "pthread_getcpuclockid failed");
|
||||||
return os::Linux::fast_thread_cpu_time(clockid);
|
return false;
|
||||||
} else {
|
}
|
||||||
// It's possible to encounter a terminated native thread that failed
|
|
||||||
// to detach itself from the VM - which should result in ESRCH.
|
if (!total) {
|
||||||
assert_status(rc == ESRCH, rc, "pthread_getcpuclockid failed");
|
clockid_t clockid_tmp = *clockid;
|
||||||
return -1;
|
clockid_tmp = (clockid_tmp & ~CLOCK_TYPE_MASK) | CPUCLOCK_VIRT;
|
||||||
}
|
*clockid = clockid_tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static jlong user_thread_cpu_time(Thread *thread);
|
||||||
|
|
||||||
|
static jlong total_thread_cpu_time(Thread *thread) {
|
||||||
|
clockid_t clockid;
|
||||||
|
bool success = get_thread_clockid(thread, &clockid, true);
|
||||||
|
|
||||||
|
return success ? os::Linux::thread_cpu_time(clockid) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
|
// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
|
||||||
@@ -5009,82 +4992,34 @@ static jlong fast_cpu_time(Thread *thread) {
|
|||||||
// the fast estimate available on the platform.
|
// the fast estimate available on the platform.
|
||||||
|
|
||||||
jlong os::current_thread_cpu_time() {
|
jlong os::current_thread_cpu_time() {
|
||||||
if (os::Linux::supports_fast_thread_cpu_time()) {
|
return os::Linux::thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
|
||||||
return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
|
|
||||||
} else {
|
|
||||||
// return user + sys since the cost is the same
|
|
||||||
return slow_thread_cpu_time(Thread::current(), true /* user + sys */);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong os::thread_cpu_time(Thread* thread) {
|
jlong os::thread_cpu_time(Thread* thread) {
|
||||||
// consistent with what current_thread_cpu_time() returns
|
return total_thread_cpu_time(thread);
|
||||||
if (os::Linux::supports_fast_thread_cpu_time()) {
|
|
||||||
return fast_cpu_time(thread);
|
|
||||||
} else {
|
|
||||||
return slow_thread_cpu_time(thread, true /* user + sys */);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
|
jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
|
||||||
if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
|
if (user_sys_cpu_time) {
|
||||||
return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
|
return os::Linux::thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
|
||||||
} else {
|
} else {
|
||||||
return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time);
|
return user_thread_cpu_time(Thread::current());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
|
jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
|
||||||
if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
|
if (user_sys_cpu_time) {
|
||||||
return fast_cpu_time(thread);
|
return total_thread_cpu_time(thread);
|
||||||
} else {
|
} else {
|
||||||
return slow_thread_cpu_time(thread, user_sys_cpu_time);
|
return user_thread_cpu_time(thread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -1 on error.
|
static jlong user_thread_cpu_time(Thread *thread) {
|
||||||
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
|
clockid_t clockid;
|
||||||
pid_t tid = thread->osthread()->thread_id();
|
bool success = get_thread_clockid(thread, &clockid, false);
|
||||||
char *s;
|
|
||||||
char stat[2048];
|
|
||||||
size_t statlen;
|
|
||||||
char proc_name[64];
|
|
||||||
int count;
|
|
||||||
long sys_time, user_time;
|
|
||||||
char cdummy;
|
|
||||||
int idummy;
|
|
||||||
long ldummy;
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
os::snprintf_checked(proc_name, 64, "/proc/self/task/%d/stat", tid);
|
return success ? os::Linux::thread_cpu_time(clockid) : -1;
|
||||||
fp = os::fopen(proc_name, "r");
|
|
||||||
if (fp == nullptr) return -1;
|
|
||||||
statlen = fread(stat, 1, 2047, fp);
|
|
||||||
stat[statlen] = '\0';
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
// Skip pid and the command string. Note that we could be dealing with
|
|
||||||
// weird command names, e.g. user could decide to rename java launcher
|
|
||||||
// to "java 1.4.2 :)", then the stat file would look like
|
|
||||||
// 1234 (java 1.4.2 :)) R ... ...
|
|
||||||
// We don't really need to know the command string, just find the last
|
|
||||||
// occurrence of ")" and then start parsing from there. See bug 4726580.
|
|
||||||
s = strrchr(stat, ')');
|
|
||||||
if (s == nullptr) return -1;
|
|
||||||
|
|
||||||
// Skip blank chars
|
|
||||||
do { s++; } while (s && isspace((unsigned char) *s));
|
|
||||||
|
|
||||||
count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
|
|
||||||
&cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
|
|
||||||
&ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
|
|
||||||
&user_time, &sys_time);
|
|
||||||
if (count != 13) return -1;
|
|
||||||
if (user_sys_cpu_time) {
|
|
||||||
return ((jlong)sys_time + (jlong)user_time) * (1000000000 / os::Posix::clock_tics_per_second());
|
|
||||||
} else {
|
|
||||||
return (jlong)user_time * (1000000000 / os::Posix::clock_tics_per_second());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
|
void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
|
||||||
|
|||||||
@@ -32,16 +32,12 @@
|
|||||||
class os::Linux {
|
class os::Linux {
|
||||||
friend class os;
|
friend class os;
|
||||||
|
|
||||||
static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
|
|
||||||
|
|
||||||
static address _initial_thread_stack_bottom;
|
static address _initial_thread_stack_bottom;
|
||||||
static uintptr_t _initial_thread_stack_size;
|
static uintptr_t _initial_thread_stack_size;
|
||||||
|
|
||||||
static const char *_libc_version;
|
static const char *_libc_version;
|
||||||
static const char *_libpthread_version;
|
static const char *_libpthread_version;
|
||||||
|
|
||||||
static bool _supports_fast_thread_cpu_time;
|
|
||||||
|
|
||||||
static GrowableArray<int>* _cpu_to_node;
|
static GrowableArray<int>* _cpu_to_node;
|
||||||
static GrowableArray<int>* _nindex_to_node;
|
static GrowableArray<int>* _nindex_to_node;
|
||||||
|
|
||||||
@@ -146,18 +142,7 @@ class os::Linux {
|
|||||||
static bool manually_expand_stack(JavaThread * t, address addr);
|
static bool manually_expand_stack(JavaThread * t, address addr);
|
||||||
static void expand_stack_to(address bottom);
|
static void expand_stack_to(address bottom);
|
||||||
|
|
||||||
// fast POSIX clocks support
|
static jlong thread_cpu_time(clockid_t clockid);
|
||||||
static void fast_thread_clock_init(void);
|
|
||||||
|
|
||||||
static int pthread_getcpuclockid(pthread_t tid, clockid_t *clock_id) {
|
|
||||||
return _pthread_getcpuclockid ? _pthread_getcpuclockid(tid, clock_id) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool supports_fast_thread_cpu_time() {
|
|
||||||
return _supports_fast_thread_cpu_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
static jlong fast_thread_cpu_time(clockid_t clockid);
|
|
||||||
|
|
||||||
static jlong sendfile(int out_fd, int in_fd, jlong* offset, jlong count);
|
static jlong sendfile(int out_fd, int in_fd, jlong* offset, jlong count);
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,14 @@ ProcSmapsParser::~ProcSmapsParser() {
|
|||||||
|
|
||||||
bool ProcSmapsParser::read_line() {
|
bool ProcSmapsParser::read_line() {
|
||||||
_line[0] = '\0';
|
_line[0] = '\0';
|
||||||
return ::fgets(_line, _linelen, _f) != nullptr;
|
|
||||||
|
if (::fgets(_line, _linelen, _f) == nullptr) {
|
||||||
|
// On error or EOF, ensure deterministic empty buffer
|
||||||
|
_line[0] = '\0';
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcSmapsParser::is_header_line() {
|
bool ProcSmapsParser::is_header_line() {
|
||||||
@@ -101,8 +108,6 @@ void ProcSmapsParser::scan_additional_line(ProcSmapsInfo& out) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts or continues parsing. Returns true on success,
|
|
||||||
// false on EOF or on error.
|
|
||||||
bool ProcSmapsParser::parse_next(ProcSmapsInfo& out) {
|
bool ProcSmapsParser::parse_next(ProcSmapsInfo& out) {
|
||||||
|
|
||||||
// Information about a single mapping reaches across several lines.
|
// Information about a single mapping reaches across several lines.
|
||||||
@@ -117,15 +122,13 @@ bool ProcSmapsParser::parse_next(ProcSmapsInfo& out) {
|
|||||||
assert(is_header_line(), "Not a header line: \"%s\".", _line);
|
assert(is_header_line(), "Not a header line: \"%s\".", _line);
|
||||||
scan_header_line(out);
|
scan_header_line(out);
|
||||||
|
|
||||||
// Now read until we encounter the next header line or EOF or an error.
|
while (true) {
|
||||||
bool ok = false, stop = false;
|
bool ok = read_line();
|
||||||
do {
|
if (!ok || is_header_line()) {
|
||||||
ok = read_line();
|
break; // EOF or next header
|
||||||
stop = !ok || is_header_line();
|
|
||||||
if (!stop) {
|
|
||||||
scan_additional_line(out);
|
|
||||||
}
|
}
|
||||||
} while (!stop);
|
scan_additional_line(out);
|
||||||
|
}
|
||||||
|
|
||||||
return ok;
|
return true; // always return true if a mapping was parsed
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,8 +84,7 @@ public:
|
|||||||
ProcSmapsParser(FILE* f);
|
ProcSmapsParser(FILE* f);
|
||||||
~ProcSmapsParser();
|
~ProcSmapsParser();
|
||||||
|
|
||||||
// Starts or continues parsing. Returns true on success,
|
// Starts or continues parsing. Returns true iff a mapping was parsed.
|
||||||
// false on EOF or on error.
|
|
||||||
bool parse_next(ProcSmapsInfo& out);
|
bool parse_next(ProcSmapsInfo& out);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1028,6 +1028,7 @@ char* os::realpath(const char* filename, char* outbuf, size_t outbuflen) {
|
|||||||
} else {
|
} else {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
}
|
}
|
||||||
|
ErrnoPreserver ep;
|
||||||
permit_forbidden_function::free(p); // *not* os::free
|
permit_forbidden_function::free(p); // *not* os::free
|
||||||
} else {
|
} else {
|
||||||
// Fallback for platforms struggling with modern Posix standards (AIX 5.3, 6.1). If realpath
|
// Fallback for platforms struggling with modern Posix standards (AIX 5.3, 6.1). If realpath
|
||||||
@@ -1351,6 +1352,10 @@ bool os::Posix::is_root(uid_t uid){
|
|||||||
return ROOT_UID == uid;
|
return ROOT_UID == uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool os::Posix::is_current_user_root(){
|
||||||
|
return is_root(geteuid());
|
||||||
|
}
|
||||||
|
|
||||||
bool os::Posix::matches_effective_uid_or_root(uid_t uid) {
|
bool os::Posix::matches_effective_uid_or_root(uid_t uid) {
|
||||||
return is_root(uid) || geteuid() == uid;
|
return is_root(uid) || geteuid() == uid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ public:
|
|||||||
// Returns true if given uid is root.
|
// Returns true if given uid is root.
|
||||||
static bool is_root(uid_t uid);
|
static bool is_root(uid_t uid);
|
||||||
|
|
||||||
|
// Returns true if the current user is root.
|
||||||
|
static bool is_current_user_root();
|
||||||
|
|
||||||
// Returns true if given uid is effective or root uid.
|
// Returns true if given uid is effective or root uid.
|
||||||
static bool matches_effective_uid_or_root(uid_t uid);
|
static bool matches_effective_uid_or_root(uid_t uid);
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,9 @@
|
|||||||
#if defined(LINUX)
|
#if defined(LINUX)
|
||||||
#include "os_linux.hpp"
|
#include "os_linux.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(BSD)
|
||||||
|
#include "os_bsd.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
@@ -142,6 +145,18 @@ static char* get_user_tmp_dir(const char* user, int vmid, int nspid) {
|
|||||||
jio_snprintf(buffer, TMP_BUFFER_LEN, "/proc/%d/root%s", vmid, tmpdir);
|
jio_snprintf(buffer, TMP_BUFFER_LEN, "/proc/%d/root%s", vmid, tmpdir);
|
||||||
tmpdir = buffer;
|
tmpdir = buffer;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __APPLE__
|
||||||
|
char buffer[PATH_MAX] = {0};
|
||||||
|
// Check if the current user is root and the target VM is running as non-root.
|
||||||
|
// Otherwise the output of os::get_temp_directory() is used.
|
||||||
|
//
|
||||||
|
if (os::Posix::is_current_user_root() && !os::Bsd::is_process_root(vmid)) {
|
||||||
|
int path_size = os::Bsd::get_user_tmp_dir_macos(user, vmid, buffer, sizeof buffer);
|
||||||
|
if (path_size > 0 && (size_t)path_size < sizeof buffer) {
|
||||||
|
tmpdir = buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
const char* perfdir = PERFDATA_NAME;
|
const char* perfdir = PERFDATA_NAME;
|
||||||
size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
|
size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
|
||||||
@@ -1138,7 +1153,8 @@ static void mmap_attach_shared(int vmid, char** addr, size_t* sizep, TRAPS) {
|
|||||||
|
|
||||||
// for linux, determine if vmid is for a containerized process
|
// for linux, determine if vmid is for a containerized process
|
||||||
int nspid = LINUX_ONLY(os::Linux::get_namespace_pid(vmid)) NOT_LINUX(-1);
|
int nspid = LINUX_ONLY(os::Linux::get_namespace_pid(vmid)) NOT_LINUX(-1);
|
||||||
const char* luser = get_user_name(vmid, &nspid, CHECK);
|
const char* luser = NOT_MACOS(get_user_name(vmid, &nspid, CHECK))
|
||||||
|
MACOS_ONLY(get_user_name(os::Bsd::get_process_uid(vmid)));
|
||||||
|
|
||||||
if (luser == nullptr) {
|
if (luser == nullptr) {
|
||||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||||
|
|||||||
@@ -1645,7 +1645,7 @@ static void SR_handler(int sig, siginfo_t* siginfo, void* context) {
|
|||||||
|
|
||||||
// Save and restore errno to avoid confusing native code with EINTR
|
// Save and restore errno to avoid confusing native code with EINTR
|
||||||
// after sigsuspend.
|
// after sigsuspend.
|
||||||
int old_errno = errno;
|
ErrnoPreserver ep;
|
||||||
|
|
||||||
PosixSignals::unblock_error_signals();
|
PosixSignals::unblock_error_signals();
|
||||||
|
|
||||||
@@ -1727,7 +1727,6 @@ static void SR_handler(int sig, siginfo_t* siginfo, void* context) {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = old_errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SR_initialize() {
|
static int SR_initialize() {
|
||||||
|
|||||||
@@ -1715,6 +1715,8 @@ static int _print_module(const char* fname, address base_address,
|
|||||||
// same architecture as Hotspot is running on
|
// same architecture as Hotspot is running on
|
||||||
void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
void * os::dll_load(const char *name, char *ebuf, int ebuflen) {
|
||||||
log_info(os)("attempting shared library load of %s", name);
|
log_info(os)("attempting shared library load of %s", name);
|
||||||
|
Events::log_dll_message(nullptr, "Attempting to load shared library %s", name);
|
||||||
|
|
||||||
void* result;
|
void* result;
|
||||||
JFR_ONLY(NativeLibraryLoadEvent load_event(name, &result);)
|
JFR_ONLY(NativeLibraryLoadEvent load_event(name, &result);)
|
||||||
result = LoadLibrary(name);
|
result = LoadLibrary(name);
|
||||||
@@ -4780,8 +4782,8 @@ int os::stat(const char *path, struct stat *sbuf) {
|
|||||||
path_to_target = get_path_to_target(wide_path);
|
path_to_target = get_path_to_target(wide_path);
|
||||||
if (path_to_target == nullptr) {
|
if (path_to_target == nullptr) {
|
||||||
// it is a symbolic link, but we failed to resolve it
|
// it is a symbolic link, but we failed to resolve it
|
||||||
errno = ENOENT;
|
|
||||||
os::free(wide_path);
|
os::free(wide_path);
|
||||||
|
errno = ENOENT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4792,14 +4794,14 @@ int os::stat(const char *path, struct stat *sbuf) {
|
|||||||
// if getting attributes failed, GetLastError should be called immediately after that
|
// if getting attributes failed, GetLastError should be called immediately after that
|
||||||
if (!bret) {
|
if (!bret) {
|
||||||
DWORD errcode = ::GetLastError();
|
DWORD errcode = ::GetLastError();
|
||||||
|
log_debug(os)("os::stat() failed to GetFileAttributesExW: GetLastError->%lu.", errcode);
|
||||||
|
os::free(wide_path);
|
||||||
|
os::free(path_to_target);
|
||||||
if (errcode == ERROR_FILE_NOT_FOUND || errcode == ERROR_PATH_NOT_FOUND) {
|
if (errcode == ERROR_FILE_NOT_FOUND || errcode == ERROR_PATH_NOT_FOUND) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
} else {
|
} else {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
}
|
}
|
||||||
log_debug(os)("os::stat() failed to GetFileAttributesExW: GetLastError->%lu.", errcode);
|
|
||||||
os::free(wide_path);
|
|
||||||
os::free(path_to_target);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4998,8 +5000,8 @@ int os::open(const char *path, int oflag, int mode) {
|
|||||||
path_to_target = get_path_to_target(wide_path);
|
path_to_target = get_path_to_target(wide_path);
|
||||||
if (path_to_target == nullptr) {
|
if (path_to_target == nullptr) {
|
||||||
// it is a symbolic link, but we failed to resolve it
|
// it is a symbolic link, but we failed to resolve it
|
||||||
errno = ENOENT;
|
|
||||||
os::free(wide_path);
|
os::free(wide_path);
|
||||||
|
errno = ENOENT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5273,6 +5275,7 @@ char* os::realpath(const char* filename, char* outbuf, size_t outbuflen) {
|
|||||||
} else {
|
} else {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
}
|
}
|
||||||
|
ErrnoPreserver ep;
|
||||||
permit_forbidden_function::free(p); // *not* os::free
|
permit_forbidden_function::free(p); // *not* os::free
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -50,11 +50,9 @@ double SharedRuntime::fmod_winx64(double x, double y)
|
|||||||
hx ^= sx; /* |x| */
|
hx ^= sx; /* |x| */
|
||||||
hy &= 0x7fffffff; /* |y| */
|
hy &= 0x7fffffff; /* |y| */
|
||||||
|
|
||||||
#pragma warning( disable : 4146 )
|
|
||||||
/* purge off exception values */
|
/* purge off exception values */
|
||||||
if ((hy | ly) == 0 || (hx >= 0x7ff00000) || /* y=0,or x not finite */
|
if ((hy | ly) == 0 || (hx >= 0x7ff00000) || /* y=0,or x not finite */
|
||||||
((hy | ((ly | -ly) >> 31))>0x7ff00000)) /* or y is NaN */
|
((hy | ((ly | -ly) >> 31))>0x7ff00000)) /* or y is NaN */
|
||||||
#pragma warning( default : 4146 )
|
|
||||||
return (x*y) / (x*y);
|
return (x*y) / (x*y);
|
||||||
if (hx <= hy) {
|
if (hx <= hy) {
|
||||||
if ((hx<hy) || (lx<ly)) return x; /* |x|<|y| return x */
|
if ((hx<hy) || (lx<ly)) return x; /* |x|<|y| return x */
|
||||||
|
|||||||
@@ -52,12 +52,16 @@ struct AtomicAccess::PlatformAdd {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<size_t byte_size>
|
template<size_t byte_size>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T AtomicAccess::PlatformXchg<byte_size>::operator()(T volatile* dest,
|
inline T AtomicAccess::PlatformXchg<byte_size>::operator()(T volatile* dest,
|
||||||
T exchange_value,
|
T exchange_value,
|
||||||
atomic_memory_order order) const {
|
atomic_memory_order order) const {
|
||||||
STATIC_ASSERT(byte_size == sizeof(T));
|
STATIC_ASSERT(byte_size == sizeof(T));
|
||||||
|
STATIC_ASSERT(byte_size == 4 || byte_size == 8);
|
||||||
T res = __atomic_exchange_n(dest, exchange_value, __ATOMIC_RELEASE);
|
T res = __atomic_exchange_n(dest, exchange_value, __ATOMIC_RELEASE);
|
||||||
FULL_MEM_BARRIER;
|
FULL_MEM_BARRIER;
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ inline D AtomicAccess::PlatformAdd<4>::fetch_then_add(D volatile* dest, I add_va
|
|||||||
return old_value;
|
return old_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ inline D AtomicAccess::PlatformAdd<8>::add_then_fetch(D volatile* dest, I add_va
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
||||||
|
|||||||
@@ -113,6 +113,9 @@ inline D AtomicAccess::PlatformAdd<8>::fetch_then_add(D volatile* dest, I add_va
|
|||||||
return atomic_fastcall(stub, dest, add_value);
|
return atomic_fastcall(stub, dest, add_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ inline D AtomicAccess::PlatformAdd<4>::add_then_fetch(D volatile* dest, I add_va
|
|||||||
return add_using_helper<int32_t>(ARMAtomicFuncs::_add_func, dest, add_value);
|
return add_using_helper<int32_t>(ARMAtomicFuncs::_add_func, dest, add_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|||||||
@@ -152,6 +152,9 @@ inline T AtomicAccess::PlatformCmpxchg<4>::operator()(T volatile* dest __attribu
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<size_t byte_size>
|
template<size_t byte_size>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T AtomicAccess::PlatformXchg<byte_size>::operator()(T volatile* dest,
|
inline T AtomicAccess::PlatformXchg<byte_size>::operator()(T volatile* dest,
|
||||||
@@ -164,6 +167,7 @@ inline T AtomicAccess::PlatformXchg<byte_size>::operator()(T volatile* dest,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATIC_ASSERT(byte_size == sizeof(T));
|
STATIC_ASSERT(byte_size == sizeof(T));
|
||||||
|
STATIC_ASSERT(byte_size == 4 || byte_size == 8);
|
||||||
|
|
||||||
if (order != memory_order_relaxed) {
|
if (order != memory_order_relaxed) {
|
||||||
FULL_MEM_BARRIER;
|
FULL_MEM_BARRIER;
|
||||||
|
|||||||
@@ -209,6 +209,9 @@ inline D AtomicAccess::PlatformAdd<8>::add_then_fetch(D volatile* dest, I inc,
|
|||||||
//
|
//
|
||||||
// The return value is the (unchanged) value from memory as it was when the
|
// The return value is the (unchanged) value from memory as it was when the
|
||||||
// replacement succeeded.
|
// replacement succeeded.
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ inline D AtomicAccess::PlatformAdd<4>::fetch_then_add(D volatile* dest, I add_va
|
|||||||
return old_value;
|
return old_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ inline D AtomicAccess::PlatformAdd<8>::add_then_fetch(D volatile* dest, I add_va
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
inline T AtomicAccess::PlatformXchg<4>::operator()(T volatile* dest,
|
||||||
|
|||||||
@@ -68,6 +68,9 @@ DEFINE_INTRINSIC_ADD(InterlockedAdd64, __int64)
|
|||||||
|
|
||||||
#undef DEFINE_INTRINSIC_ADD
|
#undef DEFINE_INTRINSIC_ADD
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
#define DEFINE_INTRINSIC_XCHG(IntrinsicName, IntrinsicType) \
|
#define DEFINE_INTRINSIC_XCHG(IntrinsicName, IntrinsicType) \
|
||||||
template<> \
|
template<> \
|
||||||
template<typename T> \
|
template<typename T> \
|
||||||
@@ -75,6 +78,8 @@ DEFINE_INTRINSIC_ADD(InterlockedAdd64, __int64)
|
|||||||
T exchange_value, \
|
T exchange_value, \
|
||||||
atomic_memory_order order) const { \
|
atomic_memory_order order) const { \
|
||||||
STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \
|
STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \
|
||||||
|
STATIC_ASSERT(sizeof(IntrinsicType) == 4 || \
|
||||||
|
sizeof(IntrinsicType) == 8); \
|
||||||
return PrimitiveConversions::cast<T>( \
|
return PrimitiveConversions::cast<T>( \
|
||||||
IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \
|
IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \
|
||||||
PrimitiveConversions::cast<IntrinsicType>(exchange_value))); \
|
PrimitiveConversions::cast<IntrinsicType>(exchange_value))); \
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ DEFINE_INTRINSIC_ADD(InterlockedAdd64, __int64)
|
|||||||
|
|
||||||
#undef DEFINE_INTRINSIC_ADD
|
#undef DEFINE_INTRINSIC_ADD
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct AtomicAccess::PlatformXchg<1> : AtomicAccess::XchgUsingCmpxchg<1> {};
|
||||||
|
|
||||||
#define DEFINE_INTRINSIC_XCHG(IntrinsicName, IntrinsicType) \
|
#define DEFINE_INTRINSIC_XCHG(IntrinsicName, IntrinsicType) \
|
||||||
template<> \
|
template<> \
|
||||||
template<typename T> \
|
template<typename T> \
|
||||||
@@ -77,6 +80,8 @@ DEFINE_INTRINSIC_ADD(InterlockedAdd64, __int64)
|
|||||||
T exchange_value, \
|
T exchange_value, \
|
||||||
atomic_memory_order order) const { \
|
atomic_memory_order order) const { \
|
||||||
STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \
|
STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \
|
||||||
|
STATIC_ASSERT(sizeof(IntrinsicType) == 4 || \
|
||||||
|
sizeof(IntrinsicType) == 8); \
|
||||||
return PrimitiveConversions::cast<T>( \
|
return PrimitiveConversions::cast<T>( \
|
||||||
IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \
|
IntrinsicName(reinterpret_cast<IntrinsicType volatile *>(dest), \
|
||||||
PrimitiveConversions::cast<IntrinsicType>(exchange_value))); \
|
PrimitiveConversions::cast<IntrinsicType>(exchange_value))); \
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ typedef CodeBuffer::csize_t csize_t; // file-local definition
|
|||||||
|
|
||||||
// External buffer, in a predefined CodeBlob.
|
// External buffer, in a predefined CodeBlob.
|
||||||
// Important: The code_start must be taken exactly, and not realigned.
|
// Important: The code_start must be taken exactly, and not realigned.
|
||||||
CodeBuffer::CodeBuffer(CodeBlob* blob) DEBUG_ONLY(: Scrubber(this, sizeof(*this))) {
|
CodeBuffer::CodeBuffer(const CodeBlob* blob) DEBUG_ONLY(: Scrubber(this, sizeof(*this))) {
|
||||||
// Provide code buffer with meaningful name
|
// Provide code buffer with meaningful name
|
||||||
initialize_misc(blob->name());
|
initialize_misc(blob->name());
|
||||||
initialize(blob->content_begin(), blob->content_size());
|
initialize(blob->content_begin(), blob->content_size());
|
||||||
|
|||||||
@@ -672,7 +672,7 @@ class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (2) CodeBuffer referring to pre-allocated CodeBlob.
|
// (2) CodeBuffer referring to pre-allocated CodeBlob.
|
||||||
CodeBuffer(CodeBlob* blob);
|
CodeBuffer(const CodeBlob* blob);
|
||||||
|
|
||||||
// (3) code buffer allocating codeBlob memory for code & relocation
|
// (3) code buffer allocating codeBlob memory for code & relocation
|
||||||
// info but with lazy initialization. The name must be something
|
// info but with lazy initialization. The name must be something
|
||||||
|
|||||||
@@ -86,9 +86,9 @@ void AOTMappedHeapWriter::init() {
|
|||||||
if (CDSConfig::is_dumping_heap()) {
|
if (CDSConfig::is_dumping_heap()) {
|
||||||
Universe::heap()->collect(GCCause::_java_lang_system_gc);
|
Universe::heap()->collect(GCCause::_java_lang_system_gc);
|
||||||
|
|
||||||
_buffer_offset_to_source_obj_table = new BufferOffsetToSourceObjectTable(/*size (prime)*/36137, /*max size*/1 * M);
|
_buffer_offset_to_source_obj_table = new (mtClassShared) BufferOffsetToSourceObjectTable(/*size (prime)*/36137, /*max size*/1 * M);
|
||||||
_dumped_interned_strings = new (mtClass)DumpedInternedStrings(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE);
|
_dumped_interned_strings = new (mtClass)DumpedInternedStrings(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE);
|
||||||
_fillers = new FillersTable();
|
_fillers = new (mtClassShared) FillersTable();
|
||||||
_requested_bottom = nullptr;
|
_requested_bottom = nullptr;
|
||||||
_requested_top = nullptr;
|
_requested_top = nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -96,6 +96,7 @@
|
|||||||
#include "runtime/vmOperations.hpp"
|
#include "runtime/vmOperations.hpp"
|
||||||
#include "runtime/vmThread.hpp"
|
#include "runtime/vmThread.hpp"
|
||||||
#include "sanitizers/leak.hpp"
|
#include "sanitizers/leak.hpp"
|
||||||
|
#include "services/management.hpp"
|
||||||
#include "utilities/align.hpp"
|
#include "utilities/align.hpp"
|
||||||
#include "utilities/bitMap.inline.hpp"
|
#include "utilities/bitMap.inline.hpp"
|
||||||
#include "utilities/defaultStream.hpp"
|
#include "utilities/defaultStream.hpp"
|
||||||
@@ -2204,7 +2205,7 @@ void AOTMetaspace::initialize_shared_spaces() {
|
|||||||
CountSharedSymbols cl;
|
CountSharedSymbols cl;
|
||||||
SymbolTable::shared_symbols_do(&cl);
|
SymbolTable::shared_symbols_do(&cl);
|
||||||
tty->print_cr("Number of shared symbols: %zu", cl.total());
|
tty->print_cr("Number of shared symbols: %zu", cl.total());
|
||||||
if (HeapShared::is_loading_mapping_mode()) {
|
if (HeapShared::is_loading() && HeapShared::is_loading_mapping_mode()) {
|
||||||
tty->print_cr("Number of shared strings: %zu", StringTable::shared_entry_count());
|
tty->print_cr("Number of shared strings: %zu", StringTable::shared_entry_count());
|
||||||
}
|
}
|
||||||
tty->print_cr("VM version: %s\r\n", static_mapinfo->vm_version());
|
tty->print_cr("VM version: %s\r\n", static_mapinfo->vm_version());
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ static size_t archive_object_size(oopDesc* archive_object) {
|
|||||||
oop AOTStreamedHeapLoader::allocate_object(oopDesc* archive_object, markWord mark, size_t size, TRAPS) {
|
oop AOTStreamedHeapLoader::allocate_object(oopDesc* archive_object, markWord mark, size_t size, TRAPS) {
|
||||||
assert(!archive_object->is_stackChunk(), "no such objects are archived");
|
assert(!archive_object->is_stackChunk(), "no such objects are archived");
|
||||||
|
|
||||||
|
NoJvmtiEventsMark njem;
|
||||||
oop heap_object;
|
oop heap_object;
|
||||||
|
|
||||||
Klass* klass = archive_object->klass();
|
Klass* klass = archive_object->klass();
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ void AOTThread::initialize() {
|
|||||||
// This is important because this thread runs before JVMTI monitors are set up appropriately.
|
// This is important because this thread runs before JVMTI monitors are set up appropriately.
|
||||||
// Therefore, callbacks would not work as intended. JVMTI has no business peeking at how we
|
// Therefore, callbacks would not work as intended. JVMTI has no business peeking at how we
|
||||||
// materialize primordial objects from the AOT cache.
|
// materialize primordial objects from the AOT cache.
|
||||||
thread->toggle_is_disable_suspend();
|
thread->disable_jvmti_events();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JavaThread::vm_exit_on_osthread_failure(thread);
|
JavaThread::vm_exit_on_osthread_failure(thread);
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ InstanceKlass* LambdaProxyClassDictionary::load_and_init_lambda_proxy_class(Inst
|
|||||||
InstanceKlass* nest_host = caller_ik->nest_host(THREAD);
|
InstanceKlass* nest_host = caller_ik->nest_host(THREAD);
|
||||||
assert(nest_host == shared_nest_host, "mismatched nest host");
|
assert(nest_host == shared_nest_host, "mismatched nest host");
|
||||||
|
|
||||||
EventClassLoad class_load_start_event;
|
EventClassLoad class_load_event;
|
||||||
|
|
||||||
// Add to class hierarchy, and do possible deoptimizations.
|
// Add to class hierarchy, and do possible deoptimizations.
|
||||||
lambda_ik->add_to_hierarchy(THREAD);
|
lambda_ik->add_to_hierarchy(THREAD);
|
||||||
@@ -368,8 +368,8 @@ InstanceKlass* LambdaProxyClassDictionary::load_and_init_lambda_proxy_class(Inst
|
|||||||
if (JvmtiExport::should_post_class_load()) {
|
if (JvmtiExport::should_post_class_load()) {
|
||||||
JvmtiExport::post_class_load(THREAD, lambda_ik);
|
JvmtiExport::post_class_load(THREAD, lambda_ik);
|
||||||
}
|
}
|
||||||
if (class_load_start_event.should_commit()) {
|
if (class_load_event.should_commit()) {
|
||||||
SystemDictionary::post_class_load_event(&class_load_start_event, lambda_ik, ClassLoaderData::class_loader_data(class_loader()));
|
JFR_ONLY(SystemDictionary::post_class_load_event(&class_load_event, lambda_ik, ClassLoaderData::class_loader_data(class_loader()));)
|
||||||
}
|
}
|
||||||
|
|
||||||
lambda_ik->initialize(CHECK_NULL);
|
lambda_ik->initialize(CHECK_NULL);
|
||||||
|
|||||||
@@ -149,6 +149,10 @@ public:
|
|||||||
assert(is_loaded(), "must be loaded");
|
assert(is_loaded(), "must be loaded");
|
||||||
return _flags;
|
return _flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch Klass::access_flags.
|
||||||
|
jint access_flags() { return flags().as_int(); }
|
||||||
|
|
||||||
bool has_finalizer() {
|
bool has_finalizer() {
|
||||||
assert(is_loaded(), "must be loaded");
|
assert(is_loaded(), "must be loaded");
|
||||||
return _has_finalizer; }
|
return _has_finalizer; }
|
||||||
|
|||||||
@@ -216,15 +216,6 @@ jint ciKlass::modifier_flags() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
// ciKlass::access_flags
|
|
||||||
jint ciKlass::access_flags() {
|
|
||||||
assert(is_loaded(), "not loaded");
|
|
||||||
GUARDED_VM_ENTRY(
|
|
||||||
return get_Klass()->access_flags().as_unsigned_short();
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciKlass::misc_flags
|
// ciKlass::misc_flags
|
||||||
klass_flags_t ciKlass::misc_flags() {
|
klass_flags_t ciKlass::misc_flags() {
|
||||||
|
|||||||
@@ -122,9 +122,6 @@ public:
|
|||||||
// Fetch modifier flags.
|
// Fetch modifier flags.
|
||||||
jint modifier_flags();
|
jint modifier_flags();
|
||||||
|
|
||||||
// Fetch Klass::access_flags.
|
|
||||||
jint access_flags();
|
|
||||||
|
|
||||||
// Fetch Klass::misc_flags.
|
// Fetch Klass::misc_flags.
|
||||||
klass_flags_t misc_flags();
|
klass_flags_t misc_flags();
|
||||||
|
|
||||||
|
|||||||
@@ -89,9 +89,6 @@
|
|||||||
#if INCLUDE_CDS
|
#if INCLUDE_CDS
|
||||||
#include "classfile/systemDictionaryShared.hpp"
|
#include "classfile/systemDictionaryShared.hpp"
|
||||||
#endif
|
#endif
|
||||||
#if INCLUDE_JFR
|
|
||||||
#include "jfr/support/jfrTraceIdExtension.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// We generally try to create the oops directly when parsing, rather than
|
// We generally try to create the oops directly when parsing, rather than
|
||||||
// allocating temporary data structures and copying the bytes twice. A
|
// allocating temporary data structures and copying the bytes twice. A
|
||||||
@@ -157,6 +154,8 @@
|
|||||||
|
|
||||||
#define JAVA_26_VERSION 70
|
#define JAVA_26_VERSION 70
|
||||||
|
|
||||||
|
#define JAVA_27_VERSION 71
|
||||||
|
|
||||||
void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
|
void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
|
||||||
assert((bad_constant == JVM_CONSTANT_Module ||
|
assert((bad_constant == JVM_CONSTANT_Module ||
|
||||||
bad_constant == JVM_CONSTANT_Package) && _major_version >= JAVA_9_VERSION,
|
bad_constant == JVM_CONSTANT_Package) && _major_version >= JAVA_9_VERSION,
|
||||||
@@ -5272,8 +5271,6 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JFR_ONLY(INIT_ID(ik);)
|
|
||||||
|
|
||||||
// If we reach here, all is well.
|
// If we reach here, all is well.
|
||||||
// Now remove the InstanceKlass* from the _klass_to_deallocate field
|
// Now remove the InstanceKlass* from the _klass_to_deallocate field
|
||||||
// in order for it to not be destroyed in the ClassFileParser destructor.
|
// in order for it to not be destroyed in the ClassFileParser destructor.
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user