mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-07 09:59:37 +01:00
Compare commits
340 Commits
lbourges/W
...
jdk-23.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a13b02ce6f | ||
|
|
a7fbf37d16 | ||
|
|
290b4b9bc4 | ||
|
|
84ec30769e | ||
|
|
366d22bd69 | ||
|
|
e5348638a8 | ||
|
|
e075b95294 | ||
|
|
872ae13471 | ||
|
|
309ef3f89a | ||
|
|
a690507f62 | ||
|
|
f7b4584012 | ||
|
|
e56655f318 | ||
|
|
f0a4bb22d3 | ||
|
|
b9e89a80dc | ||
|
|
8985dab435 | ||
|
|
26e077b37e | ||
|
|
eacb0fb089 | ||
|
|
e1fab4b40f | ||
|
|
e1688ad9fd | ||
|
|
ce19269c9b | ||
|
|
f949f3fb92 | ||
|
|
c644570cdc | ||
|
|
6f26d55846 | ||
|
|
73b2341c67 | ||
|
|
dc5298e930 | ||
|
|
14aedb575c | ||
|
|
9ed9510da7 | ||
|
|
858118eef8 | ||
|
|
6317a5aeb3 | ||
|
|
9b56b71fb2 | ||
|
|
f3be5928ed | ||
|
|
daa67f45f0 | ||
|
|
16f279c0dc | ||
|
|
f83e64334e | ||
|
|
cd61f97c2d | ||
|
|
64200b36a2 | ||
|
|
b42831630d | ||
|
|
cf75776d9e | ||
|
|
caa8f35ed4 | ||
|
|
56fcf0b1d4 | ||
|
|
46abc06df2 | ||
|
|
a858c2760c | ||
|
|
d470f69005 | ||
|
|
6d9d35b1fe | ||
|
|
9c61a138bb | ||
|
|
43e1328119 | ||
|
|
c326ff120f | ||
|
|
dd1741c18e | ||
|
|
babd6cdaac | ||
|
|
126d9c0c28 | ||
|
|
167d346708 | ||
|
|
ff8ac15ab5 | ||
|
|
f01f213d7e | ||
|
|
4e422da848 | ||
|
|
6cd7c13a30 | ||
|
|
83aab07c9a | ||
|
|
605f8dda34 | ||
|
|
2273ff9089 | ||
|
|
577dbe6256 | ||
|
|
f9c82e4929 | ||
|
|
35290fa353 | ||
|
|
ce8175651b | ||
|
|
d1bd5c087d | ||
|
|
38910d8e5b | ||
|
|
c49ef0421f | ||
|
|
0be27bf0c5 | ||
|
|
9fdcee9d2b | ||
|
|
ff109accea | ||
|
|
6250c5d156 | ||
|
|
54602276bc | ||
|
|
8915084e99 | ||
|
|
c2b57598ec | ||
|
|
55ef494737 | ||
|
|
5de6c65a55 | ||
|
|
efefa5975a | ||
|
|
e2f4c7a110 | ||
|
|
1c812b5d8a | ||
|
|
55d680c98d | ||
|
|
fd43645a84 | ||
|
|
d33912a939 | ||
|
|
8e9f46a0f1 | ||
|
|
de15bd59b2 | ||
|
|
c86367305d | ||
|
|
182be02124 | ||
|
|
81e186b0c2 | ||
|
|
8f507a34cd | ||
|
|
29cb103a9d | ||
|
|
f5f46a4b51 | ||
|
|
dc23fd61c5 | ||
|
|
66c8968e50 | ||
|
|
6b1c1aca2d | ||
|
|
eef1c1b191 | ||
|
|
f4fc1b6a58 | ||
|
|
d1150a3524 | ||
|
|
bbbe1e5395 | ||
|
|
7ea869124c | ||
|
|
a3fde486b1 | ||
|
|
047c522c4f | ||
|
|
bc91929c4a | ||
|
|
cc6f90a77b | ||
|
|
6b9dcdbcb2 | ||
|
|
a55e476321 | ||
|
|
bd44358ae6 | ||
|
|
f63b70216f | ||
|
|
faa89f4515 | ||
|
|
b8d01b0ece | ||
|
|
fa008ded77 | ||
|
|
e4badd4b10 | ||
|
|
20c1153efa | ||
|
|
caf28d4ac5 | ||
|
|
54bb851b92 | ||
|
|
af36472270 | ||
|
|
5979904902 | ||
|
|
547a229b53 | ||
|
|
37507635d5 | ||
|
|
c212fe63a1 | ||
|
|
7f9c4ab4e5 | ||
|
|
a21db48de1 | ||
|
|
8f53f5155e | ||
|
|
127a68a409 | ||
|
|
73313ef14f | ||
|
|
a6754f31cf | ||
|
|
faea17a3f5 | ||
|
|
ac8e8da546 | ||
|
|
d98335de7a | ||
|
|
3e84943e9b | ||
|
|
227fc468a4 | ||
|
|
f7d38e1c2d | ||
|
|
d1a883aa43 | ||
|
|
bf45fbdc1d | ||
|
|
b2162ba41b | ||
|
|
4b75cb0620 | ||
|
|
ef87a06537 | ||
|
|
9935c12398 | ||
|
|
d0a23213ac | ||
|
|
325d5c87cd | ||
|
|
691c55ab5c | ||
|
|
7d49c52272 | ||
|
|
a695694278 | ||
|
|
8eea53cad0 | ||
|
|
3e4583b12e | ||
|
|
ee1f2f6e48 | ||
|
|
8cb44626ae | ||
|
|
7bdece3938 | ||
|
|
b8037f835b | ||
|
|
5c4fdea834 | ||
|
|
bf77a6cf92 | ||
|
|
9e1b46f534 | ||
|
|
17c3506d5c | ||
|
|
069283b619 | ||
|
|
3e84510822 | ||
|
|
447800fab1 | ||
|
|
39884205fb | ||
|
|
be9b43c23f | ||
|
|
5c32f21d23 | ||
|
|
9ad2e63f17 | ||
|
|
a4dcbb3bc6 | ||
|
|
403fa3760f | ||
|
|
a67b103bfe | ||
|
|
e30a9614c5 | ||
|
|
0cf6cc3d84 | ||
|
|
d03c704c98 | ||
|
|
2369d92f5f | ||
|
|
045c990aeb | ||
|
|
5098e8cea7 | ||
|
|
4e56ca54e7 | ||
|
|
b82bbaec4b | ||
|
|
afba2b3467 | ||
|
|
799b98e132 | ||
|
|
dde8abad8f | ||
|
|
ed24b9e62f | ||
|
|
de9f5ed9c6 | ||
|
|
677c18efeb | ||
|
|
d6046d876c | ||
|
|
fd4f33057c | ||
|
|
2820768599 | ||
|
|
66fb62a0f4 | ||
|
|
e008338747 | ||
|
|
6534917bf1 | ||
|
|
0a86e830af | ||
|
|
474db8db3c | ||
|
|
3a336fafc9 | ||
|
|
6f582f4ee3 | ||
|
|
ed242447a5 | ||
|
|
63a80004ad | ||
|
|
e514e2e953 | ||
|
|
b7ede41a2d | ||
|
|
c3d1568363 | ||
|
|
1e1e597899 | ||
|
|
2eb7709ec3 | ||
|
|
659b469e20 | ||
|
|
8b2288fd17 | ||
|
|
cfbc0417fe | ||
|
|
c40246cf5d | ||
|
|
950de6509b | ||
|
|
d07767c6c9 | ||
|
|
a523870d86 | ||
|
|
9704054a00 | ||
|
|
91d6d15d1c | ||
|
|
1db2bb039f | ||
|
|
946c6cc6c7 | ||
|
|
302c064a90 | ||
|
|
6a6591e88c | ||
|
|
b5df5714f0 | ||
|
|
3fc154dd6d | ||
|
|
728d401ebe | ||
|
|
246e2a6492 | ||
|
|
122523e727 | ||
|
|
db10ad69ba | ||
|
|
6ad484a475 | ||
|
|
48676ccf5f | ||
|
|
c7e7b90762 | ||
|
|
15dc8974a9 | ||
|
|
4e22d8c050 | ||
|
|
c0d0292a21 | ||
|
|
dbbaa9e632 | ||
|
|
82220915e5 | ||
|
|
2288c052e6 | ||
|
|
cc687e87d9 | ||
|
|
5473e9e488 | ||
|
|
dfbb5e3ffa | ||
|
|
9805cbbd25 | ||
|
|
65197a3207 | ||
|
|
e83e2b305e | ||
|
|
0c82e4bf19 | ||
|
|
88775f95f2 | ||
|
|
c5f294b439 | ||
|
|
39aab17724 | ||
|
|
e9d86d853f | ||
|
|
821a3aa53e | ||
|
|
8883b15634 | ||
|
|
ec1782cd5b | ||
|
|
024b39c36b | ||
|
|
7afb958e8d | ||
|
|
d876cacf73 | ||
|
|
7aaf83df1d | ||
|
|
f2e126dd5f | ||
|
|
73e83a3e19 | ||
|
|
30260adb13 | ||
|
|
cf1b618dc7 | ||
|
|
58a274dc23 | ||
|
|
794cd0e591 | ||
|
|
343da68432 | ||
|
|
d7b7c1724d | ||
|
|
e4d80b1f6c | ||
|
|
5162e1a31c | ||
|
|
908d1e92fc | ||
|
|
fd3860685d | ||
|
|
a106e522f8 | ||
|
|
52cd9bb534 | ||
|
|
7cc50a181a | ||
|
|
cfbfe4a472 | ||
|
|
d1373a2fd6 | ||
|
|
0a9e3bfc90 | ||
|
|
06191aca86 | ||
|
|
9620b912dd | ||
|
|
e991c0f921 | ||
|
|
4ca2e48acb | ||
|
|
6720685abd | ||
|
|
4aab58be4a | ||
|
|
5cfaec2df8 | ||
|
|
13e53b8e3d | ||
|
|
5b9ecb1786 | ||
|
|
8f5c6e6b02 | ||
|
|
70ad622bc2 | ||
|
|
ca37a482cc | ||
|
|
ae10055b2c | ||
|
|
4e52320979 | ||
|
|
e0dad6d5ae | ||
|
|
bbbfb7ff61 | ||
|
|
2f60d36848 | ||
|
|
b415b98139 | ||
|
|
90d5b5b4c4 | ||
|
|
653c481d71 | ||
|
|
10b28babe5 | ||
|
|
d383365ea4 | ||
|
|
2723ffa8ed | ||
|
|
a4f938c623 | ||
|
|
b6d0ead93f | ||
|
|
272d11a389 | ||
|
|
58dc4c7e0e | ||
|
|
9d744b0e04 | ||
|
|
4410cdc839 | ||
|
|
9a4fc097e0 | ||
|
|
7040de19bd | ||
|
|
e5fbc631ca | ||
|
|
e78c682142 | ||
|
|
d494c21b9b | ||
|
|
87a29629e3 | ||
|
|
e2db30a534 | ||
|
|
32ed61572c | ||
|
|
62d0ee9cc0 | ||
|
|
b5bf9a6605 | ||
|
|
98fd657cfa | ||
|
|
d7b9454205 | ||
|
|
9449a53217 | ||
|
|
b5fbdb2166 | ||
|
|
2086b0f070 | ||
|
|
d1510505c1 | ||
|
|
ae49182985 | ||
|
|
1ea6456172 | ||
|
|
37ebecec88 | ||
|
|
17858b2f07 | ||
|
|
08c7c38342 | ||
|
|
fa7521b29e | ||
|
|
fbcf6d9c4f | ||
|
|
a124e6e5c7 | ||
|
|
0779f0d668 | ||
|
|
bd66b6b6f9 | ||
|
|
3edf379b67 | ||
|
|
10d81a337d | ||
|
|
1dbad8058b | ||
|
|
215149310c | ||
|
|
23f2c97f4c | ||
|
|
e84e0cdf62 | ||
|
|
2243974d29 | ||
|
|
7e6693aeba | ||
|
|
79dd575113 | ||
|
|
12a61bce8d | ||
|
|
d9dd2d19b0 | ||
|
|
b21d7b23c1 | ||
|
|
867312a7e5 | ||
|
|
a4b49253e3 | ||
|
|
86fcbe09f8 | ||
|
|
48997f54c9 | ||
|
|
4e3bfc926e | ||
|
|
d0b4f9baab | ||
|
|
cb3c45a698 | ||
|
|
63e95d8987 | ||
|
|
10f71f7dd4 | ||
|
|
a7964453cf | ||
|
|
5230786a0d | ||
|
|
378cd12f6b | ||
|
|
d96476d8bd | ||
|
|
1a43190e41 | ||
|
|
90bf3a809a | ||
|
|
b17a1c092f | ||
|
|
9e22b6dec3 | ||
|
|
fdbc2b24d3 | ||
|
|
31696a445c |
2
.github/workflows/build-cross-compile.yml
vendored
2
.github/workflows/build-cross-compile.yml
vendored
@@ -84,7 +84,7 @@ jobs:
|
||||
- target-cpu: riscv64
|
||||
gnu-arch: riscv64
|
||||
debian-arch: riscv64
|
||||
debian-repository: https://httpredir.debian.org/debian/
|
||||
debian-repository: https://snapshot.debian.org/archive/debian/20240228T034848Z/
|
||||
debian-version: sid
|
||||
tolerate-sysroot-errors: true
|
||||
|
||||
|
||||
60
.github/workflows/main.yml
vendored
60
.github/workflows/main.yml
vendored
@@ -36,7 +36,7 @@ on:
|
||||
platforms:
|
||||
description: 'Platform(s) to execute on (comma separated, e.g. "linux-x64, macos, aarch64")'
|
||||
required: true
|
||||
default: 'linux-x64, linux-x86, linux-x64-variants, linux-cross-compile, macos-x64, macos-aarch64, windows-x64, windows-aarch64, docs'
|
||||
default: 'linux-x64, linux-x86-hs, linux-x64-variants, linux-cross-compile, macos-x64, macos-aarch64, windows-x64, windows-aarch64, docs'
|
||||
configure-arguments:
|
||||
description: 'Additional configure arguments'
|
||||
required: false
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
linux-x64: ${{ steps.include.outputs.linux-x64 }}
|
||||
linux-x86: ${{ steps.include.outputs.linux-x86 }}
|
||||
linux-x86-hs: ${{ steps.include.outputs.linux-x86-hs }}
|
||||
linux-x64-variants: ${{ steps.include.outputs.linux-x64-variants }}
|
||||
linux-cross-compile: ${{ steps.include.outputs.linux-cross-compile }}
|
||||
macos-x64: ${{ steps.include.outputs.macos-x64 }}
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
}
|
||||
|
||||
echo "linux-x64=$(check_platform linux-x64 linux x64)" >> $GITHUB_OUTPUT
|
||||
echo "linux-x86=$(check_platform linux-x86 linux x86)" >> $GITHUB_OUTPUT
|
||||
echo "linux-x86-hs=$(check_platform linux-x86-hs linux x86)" >> $GITHUB_OUTPUT
|
||||
echo "linux-x64-variants=$(check_platform linux-x64-variants variants)" >> $GITHUB_OUTPUT
|
||||
echo "linux-cross-compile=$(check_platform linux-cross-compile cross-compile)" >> $GITHUB_OUTPUT
|
||||
echo "macos-x64=$(check_platform macos-x64 macos x64)" >> $GITHUB_OUTPUT
|
||||
@@ -135,12 +135,13 @@ jobs:
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.linux-x64 == 'true'
|
||||
|
||||
build-linux-x86:
|
||||
name: linux-x86
|
||||
build-linux-x86-hs:
|
||||
name: linux-x86-hs
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
with:
|
||||
platform: linux-x86
|
||||
make-target: 'hotspot'
|
||||
gcc-major-version: '10'
|
||||
gcc-package-suffix: '-multilib'
|
||||
apt-architecture: 'i386'
|
||||
@@ -150,7 +151,7 @@ jobs:
|
||||
extra-conf-options: '--with-target-bits=32 --enable-fallback-linker --enable-libffi-bundling'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.linux-x86 == 'true'
|
||||
if: needs.select.outputs.linux-x86-hs == 'true'
|
||||
|
||||
build-linux-x64-hs-nopch:
|
||||
name: linux-x64-hs-nopch
|
||||
@@ -300,16 +301,6 @@ jobs:
|
||||
bootjdk-platform: linux-x64
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
test-linux-x86:
|
||||
name: linux-x86
|
||||
needs:
|
||||
- build-linux-x86
|
||||
uses: ./.github/workflows/test.yml
|
||||
with:
|
||||
platform: linux-x86
|
||||
bootjdk-platform: linux-x64
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
test-macos-x64:
|
||||
name: macos-x64
|
||||
needs:
|
||||
@@ -347,7 +338,7 @@ jobs:
|
||||
if: always()
|
||||
needs:
|
||||
- build-linux-x64
|
||||
- build-linux-x86
|
||||
- build-linux-x86-hs
|
||||
- build-linux-x64-hs-nopch
|
||||
- build-linux-x64-hs-zero
|
||||
- build-linux-x64-hs-minimal
|
||||
@@ -358,31 +349,28 @@ jobs:
|
||||
- build-windows-x64
|
||||
- build-windows-aarch64
|
||||
- test-linux-x64
|
||||
- test-linux-x86
|
||||
- test-macos-x64
|
||||
- test-macos-aarch64
|
||||
- test-windows-x64
|
||||
|
||||
steps:
|
||||
# Hack to get hold of the api environment variables that are only defined for actions
|
||||
- name: 'Get API configuration'
|
||||
id: api
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: 'return { url: process.env["ACTIONS_RUNTIME_URL"], token: process.env["ACTIONS_RUNTIME_TOKEN"] }'
|
||||
|
||||
- name: 'Remove bundle artifacts'
|
||||
run: |
|
||||
# Find and remove all bundle artifacts
|
||||
ALL_ARTIFACT_URLS="$(curl -s \
|
||||
-H 'Accept: application/json;api-version=6.0-preview' \
|
||||
-H 'Authorization: Bearer ${{ fromJson(steps.api.outputs.result).token }}' \
|
||||
'${{ fromJson(steps.api.outputs.result).url }}_apis/pipelines/workflows/${{ github.run_id }}/artifacts?api-version=6.0-preview')"
|
||||
BUNDLE_ARTIFACT_URLS="$(echo "$ALL_ARTIFACT_URLS" | jq -r -c '.value | map(select(.name|startswith("bundles-"))) | .[].url')"
|
||||
for url in $BUNDLE_ARTIFACT_URLS; do
|
||||
echo "Removing $url"
|
||||
curl -s \
|
||||
-H 'Accept: application/json;api-version=6.0-preview' \
|
||||
-H 'Authorization: Bearer ${{ fromJson(steps.api.outputs.result).token }}' \
|
||||
-X DELETE "$url" \
|
||||
# See: https://docs.github.com/en/rest/actions/artifacts?apiVersion=2022-11-28
|
||||
ALL_ARTIFACT_IDS="$(curl -sL \
|
||||
-H 'Accept: application/vnd.github+json' \
|
||||
-H 'Authorization: Bearer ${{ github.token }}' \
|
||||
-H 'X-GitHub-Api-Version: 2022-11-28' \
|
||||
'${{ github.api_url }}/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts?per_page=100')"
|
||||
BUNDLE_ARTIFACT_IDS="$(echo "$ALL_ARTIFACT_IDS" | jq -r -c '.artifacts | map(select(.name|startswith("bundles-"))) | .[].id')"
|
||||
for id in $BUNDLE_ARTIFACT_IDS; do
|
||||
echo "Removing $id"
|
||||
curl -sL \
|
||||
-X DELETE \
|
||||
-H 'Accept: application/vnd.github+json' \
|
||||
-H 'Authorization: Bearer ${{ github.token }}' \
|
||||
-H 'X-GitHub-Api-Version: 2022-11-28' \
|
||||
"${{ github.api_url }}/repos/${{ github.repository }}/actions/artifacts/$id" \
|
||||
|| echo "Failed to remove bundle"
|
||||
done
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
[general]
|
||||
project=jdk
|
||||
project=jdk-updates
|
||||
jbs=JDK
|
||||
version=23
|
||||
version=23.0.2
|
||||
|
||||
[checks]
|
||||
error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists
|
||||
warning=issuestitle
|
||||
warning=issuestitle,binary
|
||||
|
||||
[repository]
|
||||
tags=(?:jdk-(?:[1-9]([0-9]*)(?:\.(?:0|[1-9][0-9]*)){0,4})(?:\+(?:(?:[0-9]+))|(?:-ga)))|(?:jdk[4-9](?:u\d{1,3})?-(?:(?:b\d{2,3})|(?:ga)))|(?:hs\d\d(?:\.\d{1,2})?-b\d\d)
|
||||
branches=
|
||||
branches=.*
|
||||
|
||||
[census]
|
||||
version=0
|
||||
|
||||
3
SECURITY.md
Normal file
3
SECURITY.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# JDK Vulnerabilities
|
||||
|
||||
Please follow the process outlined in the [OpenJDK Vulnerability Policy](https://openjdk.org/groups/vulnerability/report) to disclose vulnerabilities in the JDK.
|
||||
@@ -614,10 +614,9 @@ be accepted by <code>configure</code>.</p>
|
||||
<code>--with-toolchain-type=clang</code>.</p>
|
||||
<h3 id="apple-xcode">Apple Xcode</h3>
|
||||
<p>The oldest supported version of Xcode is 13.0.</p>
|
||||
<p>You will need the Xcode command line developer tools to be able to
|
||||
build the JDK. (Actually, <em>only</em> the command line tools are
|
||||
needed, not the IDE.) The simplest way to install these is to run:</p>
|
||||
<pre><code>xcode-select --install</code></pre>
|
||||
<p>You will need to download Xcode either from the App Store or specific
|
||||
versions can be easily located via the <a
|
||||
href="https://xcodereleases.com">Xcode Releases</a> website.</p>
|
||||
<p>When updating Xcode, it is advisable to keep an older version for
|
||||
building the JDK. To use a specific version of Xcode you have multiple
|
||||
options:</p>
|
||||
|
||||
@@ -422,13 +422,9 @@ To use clang instead of gcc on Linux, use `--with-toolchain-type=clang`.
|
||||
|
||||
The oldest supported version of Xcode is 13.0.
|
||||
|
||||
You will need the Xcode command line developer tools to be able to build the
|
||||
JDK. (Actually, *only* the command line tools are needed, not the IDE.) The
|
||||
simplest way to install these is to run:
|
||||
|
||||
```
|
||||
xcode-select --install
|
||||
```
|
||||
You will need to download Xcode either from the App Store or specific versions
|
||||
can be easily located via the [Xcode Releases](https://xcodereleases.com)
|
||||
website.
|
||||
|
||||
When updating Xcode, it is advisable to keep an older version for building the
|
||||
JDK. To use a specific version of Xcode you have multiple options:
|
||||
|
||||
@@ -313,9 +313,11 @@ AC_OUTPUT
|
||||
|
||||
# After AC_OUTPUT, we need to do final work
|
||||
CUSTOM_CONFIG_OUTPUT_GENERATED_HOOK
|
||||
BASIC_POST_CONFIG_OUTPUT
|
||||
|
||||
# Finally output some useful information to the user
|
||||
HELP_PRINT_SUMMARY_AND_WARNINGS
|
||||
CUSTOM_SUMMARY_AND_WARNINGS_HOOK
|
||||
HELP_REPEAT_WARNINGS
|
||||
|
||||
# All output is done. Do the post-config output management.
|
||||
BASIC_POST_CONFIG_OUTPUT
|
||||
|
||||
@@ -496,9 +496,15 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_LEAK_SANITIZER],
|
||||
#
|
||||
AC_DEFUN_ONCE([JDKOPT_SETUP_UNDEFINED_BEHAVIOR_SANITIZER],
|
||||
[
|
||||
UTIL_ARG_WITH(NAME: additional-ubsan-checks, TYPE: string,
|
||||
DEFAULT: [],
|
||||
DESC: [Customizes the ubsan checks],
|
||||
OPTIONAL: true)
|
||||
|
||||
# GCC reports lots of likely false positives for stringop-truncation and format-overflow.
|
||||
# Silence them for now.
|
||||
UBSAN_CHECKS="-fsanitize=undefined -fsanitize=float-divide-by-zero -fno-sanitize=shift-base -fno-sanitize=alignment"
|
||||
UBSAN_CHECKS="-fsanitize=undefined -fsanitize=float-divide-by-zero -fno-sanitize=shift-base -fno-sanitize=alignment \
|
||||
$ADDITIONAL_UBSAN_CHECKS"
|
||||
UBSAN_CFLAGS="$UBSAN_CHECKS -Wno-stringop-truncation -Wno-format-overflow -fno-omit-frame-pointer -DUNDEFINED_BEHAVIOR_SANITIZER"
|
||||
UBSAN_LDFLAGS="$UBSAN_CHECKS"
|
||||
UTIL_ARG_ENABLE(NAME: ubsan, DEFAULT: false, RESULT: UBSAN_ENABLED,
|
||||
|
||||
@@ -70,6 +70,25 @@ AC_DEFUN_ONCE([LIB_SETUP_ALSA],
|
||||
PKG_CHECK_MODULES(ALSA, alsa, [ALSA_FOUND=yes], [ALSA_FOUND=no])
|
||||
fi
|
||||
fi
|
||||
if test "x$ALSA_FOUND" = xno; then
|
||||
# If we have sysroot set, and no explicit library location is set,
|
||||
# look at known locations in sysroot.
|
||||
if test "x$SYSROOT" != "x" && test "x${with_alsa_lib}" == x; then
|
||||
if test -f "$SYSROOT/usr/lib64/libasound.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
|
||||
ALSA_LIBS="-L$SYSROOT/usr/lib64 -lasound"
|
||||
ALSA_FOUND=yes
|
||||
elif test -f "$SYSROOT/usr/lib/libasound.so"; then
|
||||
ALSA_LIBS="-L$SYSROOT/usr/lib -lasound"
|
||||
ALSA_FOUND=yes
|
||||
elif test -f "$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libasound.so"; then
|
||||
ALSA_LIBS="-L$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI -lasound"
|
||||
ALSA_FOUND=yes
|
||||
elif test -f "$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU_AUTOCONF-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libasound.so"; then
|
||||
ALSA_LIBS="-L$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU_AUTOCONF-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI -lasound"
|
||||
ALSA_FOUND=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "x$ALSA_FOUND" = xno; then
|
||||
AC_CHECK_HEADERS([alsa/asoundlib.h],
|
||||
[
|
||||
|
||||
@@ -71,9 +71,9 @@ AC_DEFUN_ONCE([LIB_SETUP_X11],
|
||||
elif test -f "$SYSROOT/usr/lib/libX11.so"; then
|
||||
x_libraries="$SYSROOT/usr/lib"
|
||||
elif test -f "$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libX11.so"; then
|
||||
x_libraries="$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libX11.so"
|
||||
x_libraries="$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI"
|
||||
elif test -f "$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU_AUTOCONF-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libX11.so"; then
|
||||
x_libraries="$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU_AUTOCONF-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libX11.so"
|
||||
x_libraries="$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU_AUTOCONF-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -358,6 +358,11 @@ AC_DEFUN([TOOLCHAIN_EXTRACT_COMPILER_VERSION],
|
||||
# Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
# This is free software; see the source for copying conditions. There is NO
|
||||
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# or look like
|
||||
# gcc (GCC) 10.2.1 20200825 (Alibaba 10.2.1-3.8 2.32)
|
||||
# Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
# This is free software; see the source for copying conditions. There is NO
|
||||
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
COMPILER_VERSION_OUTPUT=`$COMPILER --version 2>&1`
|
||||
# Check that this is likely to be GCC.
|
||||
$ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Free Software Foundation" > /dev/null
|
||||
@@ -371,7 +376,8 @@ AC_DEFUN([TOOLCHAIN_EXTRACT_COMPILER_VERSION],
|
||||
COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT | \
|
||||
$SED -e 's/ *Copyright .*//'`
|
||||
COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \
|
||||
$SED -e 's/^.* \(@<:@1-9@:>@<:@0-9@:>@*\.@<:@0-9.@:>@*\)@<:@^0-9.@:>@.*$/\1/'`
|
||||
$AWK -F ')' '{print [$]2}' | \
|
||||
$AWK '{print [$]1}'`
|
||||
elif test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
# clang --version output typically looks like
|
||||
# Apple clang version 15.0.0 (clang-1500.3.9.4)
|
||||
|
||||
@@ -29,17 +29,17 @@ GTEST_VERSION=1.14.0
|
||||
JTREG_VERSION=7.3.1+1
|
||||
|
||||
LINUX_X64_BOOT_JDK_EXT=tar.gz
|
||||
LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk22/830ec9fcccef480bb3e73fb7ecafe059/36/GPL/openjdk-22_linux-x64_bin.tar.gz
|
||||
LINUX_X64_BOOT_JDK_SHA256=4d65cc6ed28711768fd72c2043a7925f7c83f5f51bb64970bd9d52f7791fc6ac
|
||||
|
||||
MACOS_X64_BOOT_JDK_EXT=tar.gz
|
||||
MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk22/830ec9fcccef480bb3e73fb7ecafe059/36/GPL/openjdk-22_macos-x64_bin.tar.gz
|
||||
MACOS_X64_BOOT_JDK_SHA256=ae31fe10916429e3fe284266095067a5ce9fecbdc03ff1a079d20459f731ca36
|
||||
LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk22.0.2/c9ecb94cd31b495da20a27d4581645e8/9/GPL/openjdk-22.0.2_linux-x64_bin.tar.gz
|
||||
LINUX_X64_BOOT_JDK_SHA256=41536f115668308ecf4eba92aaf6acaeb0936225828b741efd83b6173ba82963
|
||||
|
||||
MACOS_AARCH64_BOOT_JDK_EXT=tar.gz
|
||||
MACOS_AARCH64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk22/830ec9fcccef480bb3e73fb7ecafe059/36/GPL/openjdk-22_macos-aarch64_bin.tar.gz
|
||||
MACOS_AARCH64_BOOT_JDK_SHA256=d10f82429d01047968c52c7975c326388cb5d212791e14c1de21c987463a4b53
|
||||
MACOS_AARCH64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk22.0.2/c9ecb94cd31b495da20a27d4581645e8/9/GPL/openjdk-22.0.2_macos-aarch64_bin.tar.gz
|
||||
MACOS_AARCH64_BOOT_JDK_SHA256=3dab98730234e1a87aec14bcb8171d2cae101e96ff4eed1dab96abbb08e843fd
|
||||
|
||||
MACOS_X64_BOOT_JDK_EXT=tar.gz
|
||||
MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk22.0.2/c9ecb94cd31b495da20a27d4581645e8/9/GPL/openjdk-22.0.2_macos-x64_bin.tar.gz
|
||||
MACOS_X64_BOOT_JDK_SHA256=e8b3ec7a7077711223d31156e771f11723cd7af31c2017f1bd2eda20855940fb
|
||||
|
||||
WINDOWS_X64_BOOT_JDK_EXT=zip
|
||||
WINDOWS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk22/830ec9fcccef480bb3e73fb7ecafe059/36/GPL/openjdk-22_windows-x64_bin.zip
|
||||
WINDOWS_X64_BOOT_JDK_SHA256=8f5138fecb53c08c20abd4fa6812f9400051f3852582a2142ffda0dff73a5824
|
||||
WINDOWS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk22.0.2/c9ecb94cd31b495da20a27d4581645e8/9/GPL/openjdk-22.0.2_windows-x64_bin.zip
|
||||
WINDOWS_X64_BOOT_JDK_SHA256=f2a9b9ab944e71a64637fcdc6b13a1188cf02d4eb9ecf71dc927e98b3e45f5dc
|
||||
|
||||
@@ -28,15 +28,15 @@
|
||||
|
||||
DEFAULT_VERSION_FEATURE=23
|
||||
DEFAULT_VERSION_INTERIM=0
|
||||
DEFAULT_VERSION_UPDATE=0
|
||||
DEFAULT_VERSION_UPDATE=2
|
||||
DEFAULT_VERSION_PATCH=0
|
||||
DEFAULT_VERSION_EXTRA1=0
|
||||
DEFAULT_VERSION_EXTRA2=0
|
||||
DEFAULT_VERSION_EXTRA3=0
|
||||
DEFAULT_VERSION_DATE=2024-09-17
|
||||
DEFAULT_VERSION_DATE=2025-01-21
|
||||
DEFAULT_VERSION_CLASSFILE_MAJOR=67 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
||||
DEFAULT_VERSION_CLASSFILE_MINOR=0
|
||||
DEFAULT_VERSION_DOCS_API_SINCE=11
|
||||
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="22 23"
|
||||
DEFAULT_JDK_SOURCE_TARGET_VERSION=23
|
||||
DEFAULT_PROMOTED_VERSION_PRE=ea
|
||||
DEFAULT_PROMOTED_VERSION_PRE=
|
||||
|
||||
@@ -786,7 +786,10 @@ public class CLDRConverter {
|
||||
String tzKey = Optional.ofNullable((String)handlerSupplMeta.get(tzid))
|
||||
.orElse(tzid);
|
||||
// Follow link, if needed
|
||||
var tzLink = tzdbLinks.get(tzKey);
|
||||
String tzLink = null;
|
||||
for (var k = tzKey; tzdbLinks.containsKey(k);) {
|
||||
k = tzLink = tzdbLinks.get(k);
|
||||
}
|
||||
if (tzLink == null && tzdbLinks.containsValue(tzKey)) {
|
||||
// reverse link search
|
||||
// this is needed as in tzdb, "America/Buenos_Aires" links to
|
||||
@@ -1214,7 +1217,7 @@ public class CLDRConverter {
|
||||
private static Set<String> getAvailableZoneIds() {
|
||||
assert handlerMetaZones != null;
|
||||
if (AVAILABLE_TZIDS == null) {
|
||||
AVAILABLE_TZIDS = new HashSet<>(ZoneId.getAvailableZoneIds());
|
||||
AVAILABLE_TZIDS = new HashSet<>(Arrays.asList(TimeZone.getAvailableIDs()));
|
||||
AVAILABLE_TZIDS.addAll(handlerMetaZones.keySet());
|
||||
AVAILABLE_TZIDS.remove(MetaZonesParseHandler.NO_METAZONE_KEY);
|
||||
}
|
||||
@@ -1372,6 +1375,7 @@ public class CLDRConverter {
|
||||
private static void generateTZDBShortNamesMap() throws IOException {
|
||||
Files.walk(Path.of(tzDataDir), 1, FileVisitOption.FOLLOW_LINKS)
|
||||
.filter(p -> p.toFile().isFile())
|
||||
.filter(p -> p.getFileName().toString().matches("africa|antarctica|asia|australasia|backward|etcetera|europe|northamerica|southamerica"))
|
||||
.forEach(p -> {
|
||||
try {
|
||||
String zone = null;
|
||||
@@ -1394,43 +1398,41 @@ public class CLDRConverter {
|
||||
}
|
||||
// remove comments in-line
|
||||
line = line.replaceAll("[ \t]*#.*", "");
|
||||
|
||||
var tokens = line.split("[ \t]+", -1);
|
||||
var token0len = tokens.length > 0 ? tokens[0].length() : 0;
|
||||
// Zone line
|
||||
if (line.startsWith("Zone")) {
|
||||
if (token0len > 0 && tokens[0].regionMatches(true, 0, "Zone", 0, token0len)) {
|
||||
if (zone != null) {
|
||||
tzdbShortNamesMap.put(zone, format + NBSP + rule);
|
||||
}
|
||||
var zl = line.split("[ \t]+", -1);
|
||||
zone = zl[1];
|
||||
rule = zl[3];
|
||||
format = flipIfNeeded(inVanguard, zl[4]);
|
||||
zone = tokens[1];
|
||||
rule = tokens[3];
|
||||
format = flipIfNeeded(inVanguard, tokens[4]);
|
||||
} else {
|
||||
if (zone != null) {
|
||||
if (line.startsWith("Rule") ||
|
||||
line.startsWith("Link")) {
|
||||
if (token0len > 0 &&
|
||||
(tokens[0].regionMatches(true, 0, "Rule", 0, token0len) ||
|
||||
tokens[0].regionMatches(true, 0, "Link", 0, token0len))) {
|
||||
tzdbShortNamesMap.put(zone, format + NBSP + rule);
|
||||
zone = null;
|
||||
rule = null;
|
||||
format = null;
|
||||
} else {
|
||||
var s = line.split("[ \t]+", -1);
|
||||
rule = s[2];
|
||||
format = flipIfNeeded(inVanguard, s[3]);
|
||||
rule = tokens[2];
|
||||
format = flipIfNeeded(inVanguard, tokens[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rule line
|
||||
if (line.startsWith("Rule")) {
|
||||
var rl = line.split("[ \t]+", -1);
|
||||
tzdbSubstLetters.put(rl[1] + NBSP + (rl[8].equals("0") ? STD : DST),
|
||||
rl[9].replace(NO_SUBST, ""));
|
||||
if (token0len > 0 && tokens[0].regionMatches(true, 0, "Rule", 0, token0len)) {
|
||||
tzdbSubstLetters.put(tokens[1] + NBSP + (tokens[8].equals("0") ? STD : DST),
|
||||
tokens[9].replace(NO_SUBST, ""));
|
||||
}
|
||||
|
||||
// Link line
|
||||
if (line.startsWith("Link")) {
|
||||
var ll = line.split("[ \t]+", -1);
|
||||
tzdbLinks.put(ll[2], ll[1]);
|
||||
if (token0len > 0 && tokens[0].regionMatches(true, 0, "Link", 0, token0len)) {
|
||||
tzdbLinks.put(tokens[2], tokens[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1491,13 +1493,14 @@ public class CLDRConverter {
|
||||
/*
|
||||
* Convert TZDB offsets to JDK's offsets, eg, "-08" to "GMT-08:00".
|
||||
* If it cannot recognize the pattern, return the argument as is.
|
||||
* Returning null results in generating the GMT format at runtime.
|
||||
*/
|
||||
private static String convertGMTName(String f) {
|
||||
try {
|
||||
// Should pre-fill GMT format once COMPAT is gone.
|
||||
// Till then, fall back to GMT format at runtime, after COMPAT short
|
||||
// names are populated
|
||||
ZoneOffset.of(f);
|
||||
if (!f.equals("%z")) {
|
||||
// Validate if the format is an offset
|
||||
ZoneOffset.of(f);
|
||||
}
|
||||
return null;
|
||||
} catch (DateTimeException dte) {
|
||||
// textual representation. return as is
|
||||
|
||||
@@ -778,7 +778,7 @@ public class FieldGen {
|
||||
result.appendLine("}");
|
||||
|
||||
result.appendLine("@Override");
|
||||
result.appendLine("protected int mult(long[] a, long[] b, long[] r) {");
|
||||
result.appendLine("protected void mult(long[] a, long[] b, long[] r) {");
|
||||
result.incrIndent();
|
||||
for (int i = 0; i < 2 * params.getNumLimbs() - 1; i++) {
|
||||
result.appendIndent();
|
||||
@@ -804,9 +804,6 @@ public class FieldGen {
|
||||
}
|
||||
}
|
||||
result.append(");\n");
|
||||
result.appendIndent();
|
||||
result.append("return 0;");
|
||||
result.appendLine();
|
||||
result.decrIndent();
|
||||
result.appendLine("}");
|
||||
|
||||
@@ -836,7 +833,7 @@ public class FieldGen {
|
||||
// }
|
||||
// }
|
||||
result.appendLine("@Override");
|
||||
result.appendLine("protected int square(long[] a, long[] r) {");
|
||||
result.appendLine("protected void square(long[] a, long[] r) {");
|
||||
result.incrIndent();
|
||||
for (int i = 0; i < 2 * params.getNumLimbs() - 1; i++) {
|
||||
result.appendIndent();
|
||||
@@ -877,9 +874,6 @@ public class FieldGen {
|
||||
}
|
||||
}
|
||||
result.append(");\n");
|
||||
result.appendIndent();
|
||||
result.append("return 0;");
|
||||
result.appendLine();
|
||||
result.decrIndent();
|
||||
result.appendLine("}");
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -107,7 +107,7 @@ public final class SealedGraph implements Taglet {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
String simpleTypeName = element.getSimpleName().toString();
|
||||
String simpleTypeName = packagelessCanonicalName(typeElement).replace('.', '/');
|
||||
String imageFile = simpleTypeName + "-sealed-graph.svg";
|
||||
int thumbnailHeight = 100; // also appears in the stylesheet
|
||||
String hoverImage = "<span>"
|
||||
@@ -315,14 +315,14 @@ public final class SealedGraph implements Taglet {
|
||||
case MEMBER -> packageName((TypeElement) element.getEnclosingElement());
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static String packagelessCanonicalName(TypeElement element) {
|
||||
String result = element.getSimpleName().toString();
|
||||
while (element.getNestingKind() == NestingKind.MEMBER) {
|
||||
element = (TypeElement) element.getEnclosingElement();
|
||||
result = element.getSimpleName().toString() + '.' + result;
|
||||
}
|
||||
return result;
|
||||
private static String packagelessCanonicalName(TypeElement element) {
|
||||
String result = element.getSimpleName().toString();
|
||||
while (element.getNestingKind() == NestingKind.MEMBER) {
|
||||
element = (TypeElement) element.getEnclosingElement();
|
||||
result = element.getSimpleName().toString() + '.' + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -164,7 +164,8 @@ class TzdbZoneRulesProvider {
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("Zone")) { // parse Zone line
|
||||
int token0len = tokens.length > 0 ? tokens[0].length() : line.length();
|
||||
if (line.regionMatches(true, 0, "Zone", 0, token0len)) { // parse Zone line
|
||||
String name = tokens[1];
|
||||
if (excludedZones.contains(name)){
|
||||
continue;
|
||||
@@ -182,13 +183,13 @@ class TzdbZoneRulesProvider {
|
||||
if (zLine.parse(tokens, 2)) {
|
||||
openZone = null;
|
||||
}
|
||||
} else if (line.startsWith("Rule")) { // parse Rule line
|
||||
} else if (line.regionMatches(true, 0, "Rule", 0, token0len)) { // parse Rule line
|
||||
String name = tokens[1];
|
||||
if (!rules.containsKey(name)) {
|
||||
rules.put(name, new ArrayList<RuleLine>(10));
|
||||
}
|
||||
rules.get(name).add(new RuleLine().parse(tokens));
|
||||
} else if (line.startsWith("Link")) { // parse link line
|
||||
} else if (line.regionMatches(true, 0, "Link", 0, token0len)) { // parse link line
|
||||
if (tokens.length >= 3) {
|
||||
String realId = tokens[1];
|
||||
String aliasId = tokens[2];
|
||||
@@ -304,7 +305,7 @@ class TzdbZoneRulesProvider {
|
||||
month = parseMonth(tokens[off++]);
|
||||
if (off < tokens.length) {
|
||||
String dayRule = tokens[off++];
|
||||
if (dayRule.startsWith("last")) {
|
||||
if (dayRule.regionMatches(true, 0, "last", 0, 4)) {
|
||||
dayOfMonth = -1;
|
||||
dayOfWeek = parseDayOfWeek(dayRule.substring(4));
|
||||
adjustForwards = false;
|
||||
@@ -355,42 +356,45 @@ class TzdbZoneRulesProvider {
|
||||
}
|
||||
|
||||
int parseYear(String year, int defaultYear) {
|
||||
switch (year.toLowerCase()) {
|
||||
case "min": return 1900;
|
||||
case "max": return Year.MAX_VALUE;
|
||||
case "only": return defaultYear;
|
||||
}
|
||||
int len = year.length();
|
||||
|
||||
if (year.regionMatches(true, 0, "minimum", 0, len)) return 1900;
|
||||
if (year.regionMatches(true, 0, "maximum", 0, len)) return Year.MAX_VALUE;
|
||||
if (year.regionMatches(true, 0, "only", 0, len)) return defaultYear;
|
||||
|
||||
return Integer.parseInt(year);
|
||||
}
|
||||
|
||||
Month parseMonth(String mon) {
|
||||
switch (mon) {
|
||||
case "Jan": return Month.JANUARY;
|
||||
case "Feb": return Month.FEBRUARY;
|
||||
case "Mar": return Month.MARCH;
|
||||
case "Apr": return Month.APRIL;
|
||||
case "May": return Month.MAY;
|
||||
case "Jun": return Month.JUNE;
|
||||
case "Jul": return Month.JULY;
|
||||
case "Aug": return Month.AUGUST;
|
||||
case "Sep": return Month.SEPTEMBER;
|
||||
case "Oct": return Month.OCTOBER;
|
||||
case "Nov": return Month.NOVEMBER;
|
||||
case "Dec": return Month.DECEMBER;
|
||||
}
|
||||
int len = mon.length();
|
||||
|
||||
if (mon.regionMatches(true, 0, "January", 0, len)) return Month.JANUARY;
|
||||
if (mon.regionMatches(true, 0, "February", 0, len)) return Month.FEBRUARY;
|
||||
if (mon.regionMatches(true, 0, "March", 0, len)) return Month.MARCH;
|
||||
if (mon.regionMatches(true, 0, "April", 0, len)) return Month.APRIL;
|
||||
if (mon.regionMatches(true, 0, "May", 0, len)) return Month.MAY;
|
||||
if (mon.regionMatches(true, 0, "June", 0, len)) return Month.JUNE;
|
||||
if (mon.regionMatches(true, 0, "July", 0, len)) return Month.JULY;
|
||||
if (mon.regionMatches(true, 0, "August", 0, len)) return Month.AUGUST;
|
||||
if (mon.regionMatches(true, 0, "September", 0, len)) return Month.SEPTEMBER;
|
||||
if (mon.regionMatches(true, 0, "October", 0, len)) return Month.OCTOBER;
|
||||
if (mon.regionMatches(true, 0, "November", 0, len)) return Month.NOVEMBER;
|
||||
if (mon.regionMatches(true, 0, "December", 0, len)) return Month.DECEMBER;
|
||||
|
||||
throw new IllegalArgumentException("Unknown month: " + mon);
|
||||
}
|
||||
|
||||
DayOfWeek parseDayOfWeek(String dow) {
|
||||
switch (dow) {
|
||||
case "Mon": return DayOfWeek.MONDAY;
|
||||
case "Tue": return DayOfWeek.TUESDAY;
|
||||
case "Wed": return DayOfWeek.WEDNESDAY;
|
||||
case "Thu": return DayOfWeek.THURSDAY;
|
||||
case "Fri": return DayOfWeek.FRIDAY;
|
||||
case "Sat": return DayOfWeek.SATURDAY;
|
||||
case "Sun": return DayOfWeek.SUNDAY;
|
||||
}
|
||||
int len = dow.length();
|
||||
|
||||
if (dow.regionMatches(true, 0, "Monday", 0, len)) return DayOfWeek.MONDAY;
|
||||
if (dow.regionMatches(true, 0, "Tuesday", 0, len)) return DayOfWeek.TUESDAY;
|
||||
if (dow.regionMatches(true, 0, "Wednesday", 0, len)) return DayOfWeek.WEDNESDAY;
|
||||
if (dow.regionMatches(true, 0, "Thursday", 0, len)) return DayOfWeek.THURSDAY;
|
||||
if (dow.regionMatches(true, 0, "Friday", 0, len)) return DayOfWeek.FRIDAY;
|
||||
if (dow.regionMatches(true, 0, "Saturday", 0, len)) return DayOfWeek.SATURDAY;
|
||||
if (dow.regionMatches(true, 0, "Sunday", 0, len)) return DayOfWeek.SUNDAY;
|
||||
|
||||
throw new IllegalArgumentException("Unknown day-of-week: " + dow);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -663,7 +663,7 @@ public class GenerateJfrFiles {
|
||||
out.write("");
|
||||
out.write("union JfrNativeSettings {");
|
||||
out.write(" // Array version.");
|
||||
out.write(" jfrNativeEventSetting bits[NUMBER_OF_EVENTS];");
|
||||
out.write(" jfrNativeEventSetting bits[NUMBER_OF_EVENTS + NUMBER_OF_RESERVED_EVENTS];");
|
||||
out.write(" // Then, to make it easy to debug,");
|
||||
out.write(" // add named struct members also.");
|
||||
out.write(" struct {");
|
||||
|
||||
@@ -869,7 +869,7 @@ BUILD_HOTSPOT_JTREG_EXECUTABLES_JDK_LIBS_exedaemonDestroy := java.base:libjvm
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT
|
||||
BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libMonitorWithDeadObjectTest.c libTestPsig.c exeGetCreatedJavaVMs.c
|
||||
BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libMonitorWithDeadObjectTest.c libTestPsig.c exeGetCreatedJavaVMs.c libTestUnloadedClass.cpp
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_JDK_LIBS_libnativeStack := java.base:libjvm
|
||||
else
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libbootclssearch_agent += -lpthread
|
||||
@@ -1509,6 +1509,7 @@ else
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libCompleteExit += -lpthread
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMonitorWithDeadObjectTest += -lpthread
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libnativeStack += -lpthread
|
||||
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libTestUnloadedClass += -lpthread
|
||||
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeGetCreatedJavaVMs := -lpthread
|
||||
BUILD_HOTSPOT_JTREG_EXECUTABLES_JDK_LIBS_exeGetCreatedJavaVMs := java.base:libjvm
|
||||
|
||||
|
||||
@@ -114,6 +114,8 @@ ifeq ($(call isTargetOs, linux), true)
|
||||
# stripping during the test libraries' build.
|
||||
BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libFib := -g
|
||||
BUILD_JDK_JTREG_LIBRARIES_STRIP_SYMBOLS_libFib := false
|
||||
# nio tests' libCreationTimeHelper native needs -ldl linker flag
|
||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libCreationTimeHelper := -ldl
|
||||
endif
|
||||
|
||||
ifeq ($(ASAN_ENABLED), true)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -76,4 +76,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
|
||||
#define USE_POINTERS_TO_REGISTER_IMPL_ARRAY
|
||||
|
||||
#define USE_TRAMPOLINE_STUB_FIX_OWNER
|
||||
|
||||
#endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP
|
||||
|
||||
@@ -1730,8 +1730,8 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl
|
||||
// The bitmap is full to bursting.
|
||||
// Implicit invariant: BITMAP_FULL implies (length > 0)
|
||||
assert(Klass::SECONDARY_SUPERS_BITMAP_FULL == ~uintx(0), "");
|
||||
cmn(r_bitmap, (u1)1);
|
||||
br(EQ, L_huge);
|
||||
cmpw(r_array_length, (u1)(Klass::SECONDARY_SUPERS_TABLE_SIZE - 2));
|
||||
br(GT, L_huge);
|
||||
|
||||
// NB! Our caller has checked bits 0 and 1 in the bitmap. The
|
||||
// current slot (at secondary_supers[r_array_index]) has not yet
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "classfile/vmClasses.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterRuntime.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
@@ -36,7 +37,7 @@
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
|
||||
#define __ _masm->
|
||||
#define __ Disassembler::hook<MacroAssembler>(__FILE__, __LINE__, _masm)->
|
||||
|
||||
#ifdef PRODUCT
|
||||
#define BLOCK_COMMENT(str) /* nothing */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -51,13 +51,18 @@ void NativeInstruction::wrote(int offset) {
|
||||
}
|
||||
|
||||
address NativeCall::destination() const {
|
||||
address addr = (address)this;
|
||||
address destination = instruction_address() + displacement();
|
||||
address addr = instruction_address();
|
||||
address destination = addr + displacement();
|
||||
|
||||
// Performance optimization: no need to call find_blob() if it is a self-call
|
||||
if (destination == addr) {
|
||||
return destination;
|
||||
}
|
||||
|
||||
// Do we use a trampoline stub for this call?
|
||||
CodeBlob* cb = CodeCache::find_blob(addr);
|
||||
assert(cb && cb->is_nmethod(), "sanity");
|
||||
nmethod *nm = (nmethod *)cb;
|
||||
assert(cb != nullptr && cb->is_nmethod(), "nmethod expected");
|
||||
nmethod *nm = cb->as_nmethod();
|
||||
if (nm->stub_contains(destination) && is_NativeCallTrampolineStub_at(destination)) {
|
||||
// Yes we do, so get the destination from the trampoline stub.
|
||||
const address trampoline_stub_addr = destination;
|
||||
@@ -72,12 +77,8 @@ address NativeCall::destination() const {
|
||||
// call instruction at all times.
|
||||
//
|
||||
// Used in the runtime linkage of calls; see class CompiledIC.
|
||||
//
|
||||
// Add parameter assert_lock to switch off assertion
|
||||
// during code generation, where no patching lock is needed.
|
||||
void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) {
|
||||
assert(!assert_lock ||
|
||||
(Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
|
||||
void NativeCall::set_destination_mt_safe(address dest) {
|
||||
assert((CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
|
||||
CompiledICLocker::is_safe(addr_at(0)),
|
||||
"concurrent code patching");
|
||||
|
||||
@@ -104,22 +105,18 @@ void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) {
|
||||
}
|
||||
|
||||
address NativeCall::get_trampoline() {
|
||||
address call_addr = addr_at(0);
|
||||
address call_addr = instruction_address();
|
||||
|
||||
CodeBlob *code = CodeCache::find_blob(call_addr);
|
||||
assert(code != nullptr, "Could not find the containing code blob");
|
||||
assert(code != nullptr && code->is_nmethod(), "nmethod expected");
|
||||
nmethod* nm = code->as_nmethod();
|
||||
|
||||
address bl_destination
|
||||
= MacroAssembler::pd_call_destination(call_addr);
|
||||
if (code->contains(bl_destination) &&
|
||||
address bl_destination = call_addr + displacement();
|
||||
if (nm->stub_contains(bl_destination) &&
|
||||
is_NativeCallTrampolineStub_at(bl_destination))
|
||||
return bl_destination;
|
||||
|
||||
if (code->is_nmethod()) {
|
||||
return trampoline_stub_Relocation::get_trampoline_for(call_addr, (nmethod*)code);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return trampoline_stub_Relocation::get_trampoline_for(call_addr, nm);
|
||||
}
|
||||
|
||||
// Inserts a native call instruction at a given pc
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2108, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -173,6 +173,7 @@ public:
|
||||
int displacement() const { return (int_at(displacement_offset) << 6) >> 4; }
|
||||
address displacement_address() const { return addr_at(displacement_offset); }
|
||||
address return_address() const { return addr_at(return_address_offset); }
|
||||
address raw_destination() const { return instruction_address() + displacement(); }
|
||||
address destination() const;
|
||||
|
||||
void set_destination(address dest) {
|
||||
@@ -212,9 +213,7 @@ public:
|
||||
//
|
||||
// Used in the runtime linkage of calls; see class CompiledIC.
|
||||
// (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.)
|
||||
|
||||
// The parameter assert_lock disables the assertion during code generation.
|
||||
void set_destination_mt_safe(address dest, bool assert_lock = true);
|
||||
void set_destination_mt_safe(address dest);
|
||||
|
||||
address get_trampoline();
|
||||
#if INCLUDE_JVMCI
|
||||
|
||||
@@ -60,13 +60,12 @@ void Relocation::pd_set_data_value(address x, bool verify_only) {
|
||||
|
||||
address Relocation::pd_call_destination(address orig_addr) {
|
||||
assert(is_call(), "should be a call here");
|
||||
if (NativeCall::is_call_at(addr())) {
|
||||
address trampoline = nativeCall_at(addr())->get_trampoline();
|
||||
if (trampoline) {
|
||||
return nativeCallTrampolineStub_at(trampoline)->destination();
|
||||
if (orig_addr == nullptr) {
|
||||
if (NativeCall::is_call_at(addr())) {
|
||||
NativeCall* call = nativeCall_at(addr());
|
||||
return call->destination();
|
||||
}
|
||||
}
|
||||
if (orig_addr != nullptr) {
|
||||
} else {
|
||||
address new_addr = MacroAssembler::pd_call_destination(orig_addr);
|
||||
// If call is branch to self, don't try to relocate it, just leave it
|
||||
// as branch to self. This happens during code generation if the code
|
||||
@@ -82,16 +81,26 @@ address Relocation::pd_call_destination(address orig_addr) {
|
||||
void Relocation::pd_set_call_destination(address x) {
|
||||
assert(is_call(), "should be a call here");
|
||||
if (NativeCall::is_call_at(addr())) {
|
||||
address trampoline = nativeCall_at(addr())->get_trampoline();
|
||||
if (trampoline) {
|
||||
nativeCall_at(addr())->set_destination_mt_safe(x, /* assert_lock */false);
|
||||
return;
|
||||
}
|
||||
NativeCall* call = nativeCall_at(addr());
|
||||
call->set_destination(x);
|
||||
} else {
|
||||
MacroAssembler::pd_patch_instruction(addr(), x);
|
||||
}
|
||||
MacroAssembler::pd_patch_instruction(addr(), x);
|
||||
assert(pd_call_destination(addr()) == x, "fail in reloc");
|
||||
}
|
||||
|
||||
void trampoline_stub_Relocation::pd_fix_owner_after_move() {
|
||||
NativeCall* call = nativeCall_at(owner());
|
||||
assert(call->raw_destination() == owner(), "destination should be empty");
|
||||
address trampoline = addr();
|
||||
address dest = nativeCallTrampolineStub_at(trampoline)->destination();
|
||||
if (!Assembler::reachable_from_branch_at(owner(), dest)) {
|
||||
dest = trampoline;
|
||||
}
|
||||
call->set_destination(dest);
|
||||
}
|
||||
|
||||
|
||||
address* Relocation::pd_address_in_code() {
|
||||
return (address*)(addr() + 8);
|
||||
}
|
||||
|
||||
@@ -30,8 +30,15 @@
|
||||
|
||||
// Java frames don't have callee saved registers (except for rfp), so we can use a smaller RegisterMap
|
||||
class SmallRegisterMap {
|
||||
constexpr SmallRegisterMap() = default;
|
||||
~SmallRegisterMap() = default;
|
||||
NONCOPYABLE(SmallRegisterMap);
|
||||
|
||||
public:
|
||||
static constexpr SmallRegisterMap* instance = nullptr;
|
||||
static const SmallRegisterMap* instance() {
|
||||
static constexpr SmallRegisterMap the_instance{};
|
||||
return &the_instance;
|
||||
}
|
||||
private:
|
||||
static void assert_is_rfp(VMReg r) NOT_DEBUG_RETURN
|
||||
DEBUG_ONLY({ assert (r == rfp->as_VMReg() || r == rfp->as_VMReg()->next(), "Reg: %s", r->name()); })
|
||||
@@ -48,17 +55,6 @@ public:
|
||||
return map;
|
||||
}
|
||||
|
||||
SmallRegisterMap() {}
|
||||
|
||||
SmallRegisterMap(const RegisterMap* map) {
|
||||
#ifdef ASSERT
|
||||
for(int i = 0; i < RegisterMap::reg_count; i++) {
|
||||
VMReg r = VMRegImpl::as_VMReg(i);
|
||||
if (map->location(r, (intptr_t*)nullptr) != nullptr) assert_is_rfp(r);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline address location(VMReg reg, intptr_t* sp) const {
|
||||
assert_is_rfp(reg);
|
||||
return (address)(sp - frame::sender_sp_offset);
|
||||
|
||||
@@ -7412,6 +7412,28 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// load Method* target of MethodHandle
|
||||
// j_rarg0 = jobject receiver
|
||||
// rmethod = result
|
||||
address generate_upcall_stub_load_target() {
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target");
|
||||
address start = __ pc();
|
||||
|
||||
__ resolve_global_jobject(j_rarg0, rscratch1, rscratch2);
|
||||
// Load target method from receiver
|
||||
__ load_heap_oop(rmethod, Address(j_rarg0, java_lang_invoke_MethodHandle::form_offset()), rscratch1, rscratch2);
|
||||
__ load_heap_oop(rmethod, Address(rmethod, java_lang_invoke_LambdaForm::vmentry_offset()), rscratch1, rscratch2);
|
||||
__ load_heap_oop(rmethod, Address(rmethod, java_lang_invoke_MemberName::method_offset()), rscratch1, rscratch2);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rmethod,
|
||||
Address(rmethod, java_lang_invoke_ResolvedMethodName::vmtarget_offset()),
|
||||
noreg, noreg);
|
||||
__ str(rmethod, Address(rthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
|
||||
|
||||
__ ret(lr);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Continuation point for throwing of implicit exceptions that are
|
||||
// not handled in the current activation. Fabricates an exception
|
||||
// oop and initiates normal exception dispatching in this
|
||||
@@ -8477,6 +8499,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
#endif
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target();
|
||||
|
||||
StubRoutines::aarch64::set_completed(); // Inidicate that arraycopy and zero_blocks stubs are generated
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "compiler/compiler_globals.hpp"
|
||||
#include "gc/shared/barrierSetAssembler.hpp"
|
||||
#include "interpreter/bytecodeHistogram.hpp"
|
||||
@@ -67,7 +68,7 @@
|
||||
// Max size with JVMTI
|
||||
int TemplateInterpreter::InterpreterCodeSize = 200 * 1024;
|
||||
|
||||
#define __ _masm->
|
||||
#define __ Disassembler::hook<InterpreterMacroAssembler>(__FILE__, __LINE__, _masm)->
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -2011,13 +2012,21 @@ void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t,
|
||||
address& vep) {
|
||||
assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
|
||||
Label L;
|
||||
aep = __ pc(); __ push_ptr(); __ b(L);
|
||||
fep = __ pc(); __ push_f(); __ b(L);
|
||||
dep = __ pc(); __ push_d(); __ b(L);
|
||||
lep = __ pc(); __ push_l(); __ b(L);
|
||||
bep = cep = sep =
|
||||
iep = __ pc(); __ push_i();
|
||||
vep = __ pc();
|
||||
aep = __ pc(); // atos entry point
|
||||
__ push_ptr();
|
||||
__ b(L);
|
||||
fep = __ pc(); // ftos entry point
|
||||
__ push_f();
|
||||
__ b(L);
|
||||
dep = __ pc(); // dtos entry point
|
||||
__ push_d();
|
||||
__ b(L);
|
||||
lep = __ pc(); // ltos entry point
|
||||
__ push_l();
|
||||
__ b(L);
|
||||
bep = cep = sep = iep = __ pc(); // [bcsi]tos entry point
|
||||
__ push_i();
|
||||
vep = __ pc(); // vtos entry point
|
||||
__ bind(L);
|
||||
generate_and_dispatch(t);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "compiler/compilerDefinitions.inline.hpp"
|
||||
#include "gc/shared/barrierSetAssembler.hpp"
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
@@ -49,7 +50,7 @@
|
||||
#include "runtime/synchronizer.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
|
||||
#define __ _masm->
|
||||
#define __ Disassembler::hook<InterpreterMacroAssembler>(__FILE__, __LINE__, _masm)->
|
||||
|
||||
// Address computation: local variables
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
@@ -117,7 +118,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
static const int upcall_stub_code_base_size = 1024;
|
||||
static const int upcall_stub_size_per_arg = 16;
|
||||
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
|
||||
BasicType* out_sig_bt, int total_out_args,
|
||||
BasicType ret_type,
|
||||
jobject jabi, jobject jconv,
|
||||
@@ -222,7 +223,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
__ block_comment("{ on_entry");
|
||||
__ lea(c_rarg0, Address(sp, frame_data_offset));
|
||||
__ movptr(c_rarg1, (intptr_t)receiver);
|
||||
__ movptr(rscratch1, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry));
|
||||
__ blr(rscratch1);
|
||||
__ mov(rthread, r0);
|
||||
@@ -238,12 +238,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
arg_shuffle.generate(_masm, as_VMStorage(shuffle_reg), abi._shadow_space_bytes, 0);
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
__ block_comment("{ receiver ");
|
||||
__ get_vm_result(j_rarg0, rthread);
|
||||
__ block_comment("} receiver ");
|
||||
|
||||
__ mov_metadata(rmethod, entry);
|
||||
__ str(rmethod, Address(rthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
|
||||
__ block_comment("{ load target ");
|
||||
__ movptr(j_rarg0, (intptr_t)receiver);
|
||||
__ far_call(RuntimeAddress(StubRoutines::upcall_stub_load_target()), rscratch1); // puts target Method* in rmethod
|
||||
__ block_comment("} load target ");
|
||||
|
||||
__ push_cont_fastpath(rthread);
|
||||
|
||||
@@ -318,7 +316,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
#ifndef PRODUCT
|
||||
stringStream ss;
|
||||
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
|
||||
ss.print("upcall_stub_%s", signature->as_C_string());
|
||||
const char* name = _masm->code_string(ss.as_string());
|
||||
#else // PRODUCT
|
||||
const char* name = "upcall_stub";
|
||||
|
||||
@@ -30,8 +30,15 @@
|
||||
|
||||
// Java frames don't have callee saved registers (except for rfp), so we can use a smaller RegisterMap
|
||||
class SmallRegisterMap {
|
||||
constexpr SmallRegisterMap() = default;
|
||||
~SmallRegisterMap() = default;
|
||||
NONCOPYABLE(SmallRegisterMap);
|
||||
|
||||
public:
|
||||
static constexpr SmallRegisterMap* instance = nullptr;
|
||||
static const SmallRegisterMap* instance() {
|
||||
static constexpr SmallRegisterMap the_instance{};
|
||||
return &the_instance;
|
||||
}
|
||||
private:
|
||||
static void assert_is_rfp(VMReg r) NOT_DEBUG_RETURN
|
||||
DEBUG_ONLY({ Unimplemented(); })
|
||||
@@ -46,12 +53,6 @@ public:
|
||||
return map;
|
||||
}
|
||||
|
||||
SmallRegisterMap() {}
|
||||
|
||||
SmallRegisterMap(const RegisterMap* map) {
|
||||
Unimplemented();
|
||||
}
|
||||
|
||||
inline address location(VMReg reg, intptr_t* sp) const {
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "prims/upcallLinker.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
|
||||
BasicType* out_sig_bt, int total_out_args,
|
||||
BasicType ret_type,
|
||||
jobject jabi, jobject jconv,
|
||||
|
||||
@@ -133,9 +133,20 @@ void LIR_Assembler::osr_entry() {
|
||||
// copied into place by code emitted in the IR.
|
||||
|
||||
Register OSR_buf = osrBufferPointer()->as_register();
|
||||
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
|
||||
int monitor_offset = BytesPerWord * method()->max_locals() +
|
||||
(2 * BytesPerWord) * (number_of_locks - 1);
|
||||
{
|
||||
assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
|
||||
|
||||
const int locals_space = BytesPerWord * method()->max_locals();
|
||||
int monitor_offset = locals_space + (2 * BytesPerWord) * (number_of_locks - 1);
|
||||
bool use_OSR_bias = false;
|
||||
|
||||
if (!Assembler::is_simm16(monitor_offset + BytesPerWord) && number_of_locks > 0) {
|
||||
// Offsets too large for ld instructions. Use bias.
|
||||
__ add_const_optimized(OSR_buf, OSR_buf, locals_space);
|
||||
monitor_offset -= locals_space;
|
||||
use_OSR_bias = true;
|
||||
}
|
||||
|
||||
// SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
|
||||
// the OSR buffer using 2 word entries: first the lock and then
|
||||
// the oop.
|
||||
@@ -161,6 +172,11 @@ void LIR_Assembler::osr_entry() {
|
||||
__ ld(R0, slot_offset + 1*BytesPerWord, OSR_buf);
|
||||
__ std(R0, mo.disp(), mo.base());
|
||||
}
|
||||
|
||||
if (use_OSR_bias) {
|
||||
// Restore.
|
||||
__ sub_const_optimized(OSR_buf, OSR_buf, locals_space);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,9 +117,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
common_abi* sender_abi = (common_abi*) fp;
|
||||
volatile common_abi* sender_abi = (common_abi*) fp; // May get updated concurrently by deoptimization!
|
||||
intptr_t* sender_sp = (intptr_t*) fp;
|
||||
address sender_pc = (address) sender_abi->lr;;
|
||||
address sender_pc = (address) sender_abi->lr;
|
||||
|
||||
if (Continuation::is_return_barrier_entry(sender_pc)) {
|
||||
// If our sender_pc is the return barrier, then our "real" sender is the continuation entry
|
||||
@@ -134,9 +134,18 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
intptr_t* unextended_sender_sp = is_interpreted_frame() ? interpreter_frame_sender_sp() : sender_sp;
|
||||
|
||||
// If the sender is a deoptimized nmethod we need to check if the original pc is valid.
|
||||
nmethod* sender_nm = sender_blob->as_nmethod_or_null();
|
||||
if (sender_nm != nullptr && sender_nm->is_deopt_pc(sender_pc)) {
|
||||
address orig_pc = *(address*)((address)unextended_sender_sp + sender_nm->orig_pc_offset());
|
||||
if (!sender_nm->insts_contains_inclusive(orig_pc)) return false;
|
||||
}
|
||||
|
||||
// It should be safe to construct the sender though it might not be valid.
|
||||
|
||||
frame sender(sender_sp, sender_pc, nullptr /* unextended_sp */, nullptr /* fp */, sender_blob);
|
||||
frame sender(sender_sp, sender_pc, unextended_sender_sp, nullptr /* fp */, sender_blob);
|
||||
|
||||
// Do we have a valid fp?
|
||||
address sender_fp = (address) sender.fp();
|
||||
|
||||
@@ -92,10 +92,10 @@ address NativeCall::destination() const {
|
||||
// Used in the runtime linkage of calls; see class CompiledIC.
|
||||
//
|
||||
// Add parameter assert_lock to switch off assertion
|
||||
// during code generation, where no patching lock is needed.
|
||||
// during code generation, where no lock is needed.
|
||||
void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) {
|
||||
assert(!assert_lock ||
|
||||
(Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
|
||||
(CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
|
||||
CompiledICLocker::is_safe(addr_at(0)),
|
||||
"concurrent code patching");
|
||||
|
||||
|
||||
@@ -3427,9 +3427,11 @@ encode %{
|
||||
call->_oop_map = _oop_map;
|
||||
call->_jvms = _jvms;
|
||||
call->_jvmadj = _jvmadj;
|
||||
call->_has_ea_local_in_scope = _has_ea_local_in_scope;
|
||||
call->_in_rms = _in_rms;
|
||||
call->_nesting = _nesting;
|
||||
call->_override_symbolic_info = _override_symbolic_info;
|
||||
call->_arg_escape = _arg_escape;
|
||||
|
||||
// New call needs all inputs of old call.
|
||||
// Req...
|
||||
|
||||
@@ -30,9 +30,16 @@
|
||||
|
||||
// Java frames don't have callee saved registers, so we can use a smaller RegisterMap
|
||||
class SmallRegisterMap {
|
||||
constexpr SmallRegisterMap() = default;
|
||||
~SmallRegisterMap() = default;
|
||||
NONCOPYABLE(SmallRegisterMap);
|
||||
|
||||
public:
|
||||
static constexpr SmallRegisterMap* instance = nullptr;
|
||||
public:
|
||||
static const SmallRegisterMap* instance() {
|
||||
static constexpr SmallRegisterMap the_instance{};
|
||||
return &the_instance;
|
||||
}
|
||||
|
||||
// as_RegisterMap is used when we didn't want to templatize and abstract over RegisterMap type to support SmallRegisterMap
|
||||
// Consider enhancing SmallRegisterMap to support those cases
|
||||
const RegisterMap* as_RegisterMap() const { return nullptr; }
|
||||
@@ -44,19 +51,6 @@ public:
|
||||
return map;
|
||||
}
|
||||
|
||||
SmallRegisterMap() {}
|
||||
|
||||
SmallRegisterMap(const RegisterMap* map) {
|
||||
#ifdef ASSERT
|
||||
for(int i = 0; i < RegisterMap::reg_count; i++) {
|
||||
VMReg r = VMRegImpl::as_VMReg(i);
|
||||
if (map->location(r, (intptr_t*)nullptr) != nullptr) {
|
||||
assert(false, "Reg: %s", r->name()); // Should not reach here
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline address location(VMReg reg, intptr_t* sp) const {
|
||||
assert(false, "Reg: %s", reg->name());
|
||||
return nullptr;
|
||||
|
||||
@@ -4728,6 +4728,30 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// load Method* target of MethodHandle
|
||||
// R3_ARG1 = jobject receiver
|
||||
// R19_method = result Method*
|
||||
address generate_upcall_stub_load_target() {
|
||||
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target");
|
||||
address start = __ pc();
|
||||
|
||||
__ resolve_global_jobject(R3_ARG1, R22_tmp2, R23_tmp3, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS);
|
||||
// Load target method from receiver
|
||||
__ load_heap_oop(R19_method, java_lang_invoke_MethodHandle::form_offset(), R3_ARG1,
|
||||
R22_tmp2, R23_tmp3, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS, IS_NOT_NULL);
|
||||
__ load_heap_oop(R19_method, java_lang_invoke_LambdaForm::vmentry_offset(), R19_method,
|
||||
R22_tmp2, R23_tmp3, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS, IS_NOT_NULL);
|
||||
__ load_heap_oop(R19_method, java_lang_invoke_MemberName::method_offset(), R19_method,
|
||||
R22_tmp2, R23_tmp3, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS, IS_NOT_NULL);
|
||||
__ ld(R19_method, java_lang_invoke_ResolvedMethodName::vmtarget_offset(), R19_method);
|
||||
__ std(R19_method, in_bytes(JavaThread::callee_target_offset()), R16_thread); // just in case callee is deoptimized
|
||||
|
||||
__ blr();
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Initialization
|
||||
void generate_initial_stubs() {
|
||||
// Generates all stubs and initializes the entry points
|
||||
@@ -4808,6 +4832,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
generate_arraycopy_stubs();
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target();
|
||||
}
|
||||
|
||||
void generate_compiler_stubs() {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
@@ -118,7 +119,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
static const int upcall_stub_code_base_size = 1024;
|
||||
static const int upcall_stub_size_per_arg = 16; // arg save & restore + move
|
||||
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
|
||||
BasicType* out_sig_bt, int total_out_args,
|
||||
BasicType ret_type,
|
||||
jobject jabi, jobject jconv,
|
||||
@@ -221,7 +222,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
__ block_comment("{ on_entry");
|
||||
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry), R0);
|
||||
__ addi(R3_ARG1, R1_SP, frame_data_offset);
|
||||
__ load_const_optimized(R4_ARG2, (intptr_t)receiver, R0);
|
||||
__ call_c(call_target_address);
|
||||
__ mr(R16_thread, R3_RET);
|
||||
__ block_comment("} on_entry");
|
||||
@@ -236,12 +236,12 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
arg_shuffle.generate(_masm, as_VMStorage(callerSP), frame::native_abi_minframe_size, frame::jit_out_preserve_size);
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
__ block_comment("{ receiver ");
|
||||
__ get_vm_result(R3_ARG1);
|
||||
__ block_comment("} receiver ");
|
||||
|
||||
__ load_const_optimized(R19_method, (intptr_t)entry);
|
||||
__ std(R19_method, in_bytes(JavaThread::callee_target_offset()), R16_thread);
|
||||
__ block_comment("{ load target ");
|
||||
__ load_const_optimized(call_target_address, StubRoutines::upcall_stub_load_target(), R0);
|
||||
__ load_const_optimized(R3_ARG1, (intptr_t)receiver, R0);
|
||||
__ mtctr(call_target_address);
|
||||
__ bctrl(); // loads target Method* into R19_method
|
||||
__ block_comment("} load target ");
|
||||
|
||||
__ push_cont_fastpath();
|
||||
|
||||
@@ -326,7 +326,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
#ifndef PRODUCT
|
||||
stringStream ss;
|
||||
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
|
||||
ss.print("upcall_stub_%s", signature->as_C_string());
|
||||
const char* name = _masm->code_string(ss.as_string());
|
||||
#else // PRODUCT
|
||||
const char* name = "upcall_stub";
|
||||
|
||||
@@ -1828,10 +1828,12 @@ enum Nf {
|
||||
// Vector unordered indexed load instructions
|
||||
INSN( vluxei8_v, 0b0000111, 0b000, 0b01, 0b0);
|
||||
INSN(vluxei32_v, 0b0000111, 0b110, 0b01, 0b0);
|
||||
INSN(vluxei64_v, 0b0000111, 0b111, 0b01, 0b0);
|
||||
|
||||
// Vector unordered indexed store instructions
|
||||
INSN( vsuxei8_v, 0b0100111, 0b000, 0b01, 0b0);
|
||||
INSN(vsuxei32_v, 0b0100111, 0b110, 0b01, 0b0);
|
||||
INSN(vsuxei64_v, 0b0100111, 0b111, 0b01, 0b0);
|
||||
|
||||
#undef INSN
|
||||
|
||||
|
||||
@@ -52,11 +52,11 @@ static void x_load_barrier_slow_path(MacroAssembler* masm, const MachNode* node,
|
||||
%}
|
||||
|
||||
// Load Pointer
|
||||
instruct xLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp)
|
||||
instruct xLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(UseZGC && !ZGenerational && (n->as_Load()->barrier_data() != 0));
|
||||
effect(TEMP dst, TEMP tmp);
|
||||
effect(TEMP dst, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(4 * DEFAULT_COST);
|
||||
|
||||
@@ -71,11 +71,11 @@ instruct xLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp)
|
||||
ins_pipe(iload_reg_mem);
|
||||
%}
|
||||
|
||||
instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
effect(TEMP_DEF res, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -105,11 +105,11 @@ instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == XLoadBarrierStrong));
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
effect(TEMP_DEF res, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -139,10 +139,10 @@ instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
effect(TEMP_DEF res, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -167,10 +167,10 @@ instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
effect(TEMP_DEF res, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -195,10 +195,10 @@ instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp, rFlagsReg cr) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
effect(TEMP_DEF prev, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -212,10 +212,10 @@ instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp, rFlagsReg cr) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() != 0));
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
effect(TEMP_DEF prev, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
|
||||
|
||||
@@ -90,11 +90,11 @@ static void z_store_barrier(MacroAssembler* masm, const MachNode* node, Address
|
||||
%}
|
||||
|
||||
// Load Pointer
|
||||
instruct zLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp)
|
||||
instruct zLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(UseZGC && ZGenerational && n->as_Load()->barrier_data() != 0);
|
||||
effect(TEMP dst, TEMP tmp);
|
||||
effect(TEMP dst, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(4 * DEFAULT_COST);
|
||||
|
||||
@@ -110,11 +110,11 @@ instruct zLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp)
|
||||
%}
|
||||
|
||||
// Store Pointer
|
||||
instruct zStoreP(memory mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2)
|
||||
instruct zStoreP(memory mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
|
||||
%{
|
||||
predicate(UseZGC && ZGenerational && n->as_Store()->barrier_data() != 0);
|
||||
match(Set mem (StoreP mem src));
|
||||
effect(TEMP tmp1, TEMP tmp2);
|
||||
effect(TEMP tmp1, TEMP tmp2, KILL cr);
|
||||
|
||||
ins_cost(125); // XXX
|
||||
format %{ "sd $mem, $src\t# ptr" %}
|
||||
@@ -127,11 +127,11 @@ instruct zStoreP(memory mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2)
|
||||
%}
|
||||
|
||||
instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -150,11 +150,11 @@ instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
|
||||
%}
|
||||
|
||||
instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -173,10 +173,10 @@ instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
|
||||
%}
|
||||
|
||||
instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -195,10 +195,10 @@ instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
%}
|
||||
|
||||
instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -216,10 +216,10 @@ instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp, rFlagsReg cr) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
effect(TEMP_DEF prev, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -234,10 +234,10 @@ instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp, rFlagsReg cr) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
effect(TEMP_DEF prev, TEMP tmp, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
|
||||
@@ -74,6 +74,16 @@ InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(
|
||||
_stack_offset = 0;
|
||||
}
|
||||
|
||||
// The C ABI specifies:
|
||||
// "integer scalars narrower than XLEN bits are widened according to the sign
|
||||
// of their type up to 32 bits, then sign-extended to XLEN bits."
|
||||
// Applies for both passed in register and stack.
|
||||
//
|
||||
// Java uses 32-bit stack slots; jint, jshort, jchar, jbyte uses one slot.
|
||||
// Native uses 64-bit stack slots for all integer scalar types.
|
||||
//
|
||||
// lw loads the Java stack slot, sign-extends and
|
||||
// sd store this widened integer into a 64 bit native stack slot.
|
||||
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
|
||||
const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
|
||||
|
||||
@@ -82,7 +92,7 @@ void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
|
||||
__ lw(reg, src);
|
||||
} else {
|
||||
__ lw(x10, src);
|
||||
__ sw(x10, Address(to(), next_stack_offset()));
|
||||
__ sd(x10, Address(to(), next_stack_offset()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,18 +146,6 @@ bool MacroAssembler::is_li32_at(address instr) {
|
||||
check_li32_data_dependency(instr);
|
||||
}
|
||||
|
||||
bool MacroAssembler::is_li64_at(address instr) {
|
||||
return is_lui_at(instr) && // lui
|
||||
is_addi_at(instr + instruction_size) && // addi
|
||||
is_slli_shift_at(instr + instruction_size * 2, 12) && // Slli Rd, Rs, 12
|
||||
is_addi_at(instr + instruction_size * 3) && // addi
|
||||
is_slli_shift_at(instr + instruction_size * 4, 12) && // Slli Rd, Rs, 12
|
||||
is_addi_at(instr + instruction_size * 5) && // addi
|
||||
is_slli_shift_at(instr + instruction_size * 6, 8) && // Slli Rd, Rs, 8
|
||||
is_addi_at(instr + instruction_size * 7) && // addi
|
||||
check_li64_data_dependency(instr);
|
||||
}
|
||||
|
||||
bool MacroAssembler::is_lwu_to_zr(address instr) {
|
||||
assert_cond(instr != nullptr);
|
||||
return (extract_opcode(instr) == 0b0000011 &&
|
||||
@@ -909,37 +897,9 @@ void MacroAssembler::li32(Register Rd, int32_t imm) {
|
||||
upper = (int32_t)upper;
|
||||
// lui Rd, imm[31:12] + imm[11]
|
||||
lui(Rd, upper);
|
||||
// use addiw to distinguish li32 to li64
|
||||
addiw(Rd, Rd, lower);
|
||||
}
|
||||
|
||||
void MacroAssembler::li64(Register Rd, int64_t imm) {
|
||||
// Load upper 32 bits. upper = imm[63:32], but if imm[31] == 1 or
|
||||
// (imm[31:20] == 0x7ff && imm[19] == 1), upper = imm[63:32] + 1.
|
||||
int64_t lower = imm & 0xffffffff;
|
||||
lower -= ((lower << 44) >> 44);
|
||||
int64_t tmp_imm = ((uint64_t)(imm & 0xffffffff00000000)) + (uint64_t)lower;
|
||||
int32_t upper = (tmp_imm - (int32_t)lower) >> 32;
|
||||
|
||||
// Load upper 32 bits
|
||||
int64_t up = upper, lo = upper;
|
||||
lo = (lo << 52) >> 52;
|
||||
up -= lo;
|
||||
up = (int32_t)up;
|
||||
lui(Rd, up);
|
||||
addi(Rd, Rd, lo);
|
||||
|
||||
// Load the rest 32 bits.
|
||||
slli(Rd, Rd, 12);
|
||||
addi(Rd, Rd, (int32_t)lower >> 20);
|
||||
slli(Rd, Rd, 12);
|
||||
lower = ((int32_t)imm << 12) >> 20;
|
||||
addi(Rd, Rd, lower);
|
||||
slli(Rd, Rd, 8);
|
||||
lower = imm & 0xff;
|
||||
addi(Rd, Rd, lower);
|
||||
}
|
||||
|
||||
void MacroAssembler::li(Register Rd, int64_t imm) {
|
||||
// int64_t is in range 0x8000 0000 0000 0000 ~ 0x7fff ffff ffff ffff
|
||||
// li -> c.li
|
||||
@@ -1586,27 +1546,6 @@ static int patch_addr_in_movptr2(address instruction_address, address target) {
|
||||
return MacroAssembler::movptr2_instruction_size;
|
||||
}
|
||||
|
||||
static int patch_imm_in_li64(address branch, address target) {
|
||||
const int LI64_INSTRUCTIONS_NUM = 8; // lui + addi + slli + addi + slli + addi + slli + addi
|
||||
int64_t lower = (intptr_t)target & 0xffffffff;
|
||||
lower = lower - ((lower << 44) >> 44);
|
||||
int64_t tmp_imm = ((uint64_t)((intptr_t)target & 0xffffffff00000000)) + (uint64_t)lower;
|
||||
int32_t upper = (tmp_imm - (int32_t)lower) >> 32;
|
||||
int64_t tmp_upper = upper, tmp_lower = upper;
|
||||
tmp_lower = (tmp_lower << 52) >> 52;
|
||||
tmp_upper -= tmp_lower;
|
||||
tmp_upper >>= 12;
|
||||
// Load upper 32 bits. Upper = target[63:32], but if target[31] = 1 or (target[31:20] == 0x7ff && target[19] == 1),
|
||||
// upper = target[63:32] + 1.
|
||||
Assembler::patch(branch + 0, 31, 12, tmp_upper & 0xfffff); // Lui.
|
||||
Assembler::patch(branch + 4, 31, 20, tmp_lower & 0xfff); // Addi.
|
||||
// Load the rest 32 bits.
|
||||
Assembler::patch(branch + 12, 31, 20, ((int32_t)lower >> 20) & 0xfff); // Addi.
|
||||
Assembler::patch(branch + 20, 31, 20, (((intptr_t)target << 44) >> 52) & 0xfff); // Addi.
|
||||
Assembler::patch(branch + 28, 31, 20, (intptr_t)target & 0xff); // Addi.
|
||||
return LI64_INSTRUCTIONS_NUM * MacroAssembler::instruction_size;
|
||||
}
|
||||
|
||||
static int patch_imm_in_li16u(address branch, uint16_t target) {
|
||||
Assembler::patch(branch, 31, 12, target); // patch lui only
|
||||
return MacroAssembler::instruction_size;
|
||||
@@ -1677,16 +1616,6 @@ static address get_target_of_movptr2(address insn_addr) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static address get_target_of_li64(address insn_addr) {
|
||||
assert_cond(insn_addr != nullptr);
|
||||
intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 44; // Lui.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)) << 32; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 12), 31, 20)) << 20; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 20), 31, 20)) << 8; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 28), 31, 20)); // Addi.
|
||||
return (address)target_address;
|
||||
}
|
||||
|
||||
address MacroAssembler::get_target_of_li32(address insn_addr) {
|
||||
assert_cond(insn_addr != nullptr);
|
||||
intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 12; // Lui.
|
||||
@@ -1709,8 +1638,6 @@ int MacroAssembler::pd_patch_instruction_size(address instruction_address, addre
|
||||
return patch_addr_in_movptr1(instruction_address, target);
|
||||
} else if (MacroAssembler::is_movptr2_at(instruction_address)) { // movptr2
|
||||
return patch_addr_in_movptr2(instruction_address, target);
|
||||
} else if (MacroAssembler::is_li64_at(instruction_address)) { // li64
|
||||
return patch_imm_in_li64(instruction_address, target);
|
||||
} else if (MacroAssembler::is_li32_at(instruction_address)) { // li32
|
||||
int64_t imm = (intptr_t)target;
|
||||
return patch_imm_in_li32(instruction_address, (int32_t)imm);
|
||||
@@ -1741,8 +1668,6 @@ address MacroAssembler::target_addr_for_insn(address insn_addr) {
|
||||
return get_target_of_movptr1(insn_addr);
|
||||
} else if (MacroAssembler::is_movptr2_at(insn_addr)) { // movptr2
|
||||
return get_target_of_movptr2(insn_addr);
|
||||
} else if (MacroAssembler::is_li64_at(insn_addr)) { // li64
|
||||
return get_target_of_li64(insn_addr);
|
||||
} else if (MacroAssembler::is_li32_at(insn_addr)) { // li32
|
||||
return get_target_of_li32(insn_addr);
|
||||
} else {
|
||||
@@ -5072,15 +4997,21 @@ static int reg2offset_out(VMReg r) {
|
||||
return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
|
||||
}
|
||||
|
||||
// On 64 bit we will store integer like items to the stack as
|
||||
// 64 bits items (riscv64 abi) even though java would only store
|
||||
// 32bits for a parameter. On 32bit it will simply be 32 bits
|
||||
// So this routine will do 32->32 on 32bit and 32->64 on 64bit
|
||||
// The C ABI specifies:
|
||||
// "integer scalars narrower than XLEN bits are widened according to the sign
|
||||
// of their type up to 32 bits, then sign-extended to XLEN bits."
|
||||
// Applies for both passed in register and stack.
|
||||
//
|
||||
// Java uses 32-bit stack slots; jint, jshort, jchar, jbyte uses one slot.
|
||||
// Native uses 64-bit stack slots for all integer scalar types.
|
||||
//
|
||||
// lw loads the Java stack slot, sign-extends and
|
||||
// sd store this widened integer into a 64 bit native stack slot.
|
||||
void MacroAssembler::move32_64(VMRegPair src, VMRegPair dst, Register tmp) {
|
||||
if (src.first()->is_stack()) {
|
||||
if (dst.first()->is_stack()) {
|
||||
// stack to stack
|
||||
ld(tmp, Address(fp, reg2offset_in(src.first())));
|
||||
lw(tmp, Address(fp, reg2offset_in(src.first())));
|
||||
sd(tmp, Address(sp, reg2offset_out(dst.first())));
|
||||
} else {
|
||||
// stack to reg
|
||||
|
||||
@@ -781,7 +781,6 @@ public:
|
||||
|
||||
void li16u(Register Rd, uint16_t imm);
|
||||
void li32(Register Rd, int32_t imm);
|
||||
void li64(Register Rd, int64_t imm);
|
||||
void li (Register Rd, int64_t imm); // optimized load immediate
|
||||
|
||||
// mv
|
||||
@@ -1676,40 +1675,6 @@ private:
|
||||
extract_rs1(last_instr) == extract_rd(add);
|
||||
}
|
||||
|
||||
// the instruction sequence of li64 is as below:
|
||||
// lui
|
||||
// addi
|
||||
// slli
|
||||
// addi
|
||||
// slli
|
||||
// addi
|
||||
// slli
|
||||
// addi
|
||||
static bool check_li64_data_dependency(address instr) {
|
||||
address lui = instr;
|
||||
address addi1 = lui + instruction_size;
|
||||
address slli1 = addi1 + instruction_size;
|
||||
address addi2 = slli1 + instruction_size;
|
||||
address slli2 = addi2 + instruction_size;
|
||||
address addi3 = slli2 + instruction_size;
|
||||
address slli3 = addi3 + instruction_size;
|
||||
address addi4 = slli3 + instruction_size;
|
||||
return extract_rs1(addi1) == extract_rd(lui) &&
|
||||
extract_rs1(addi1) == extract_rd(addi1) &&
|
||||
extract_rs1(slli1) == extract_rd(addi1) &&
|
||||
extract_rs1(slli1) == extract_rd(slli1) &&
|
||||
extract_rs1(addi2) == extract_rd(slli1) &&
|
||||
extract_rs1(addi2) == extract_rd(addi2) &&
|
||||
extract_rs1(slli2) == extract_rd(addi2) &&
|
||||
extract_rs1(slli2) == extract_rd(slli2) &&
|
||||
extract_rs1(addi3) == extract_rd(slli2) &&
|
||||
extract_rs1(addi3) == extract_rd(addi3) &&
|
||||
extract_rs1(slli3) == extract_rd(addi3) &&
|
||||
extract_rs1(slli3) == extract_rd(slli3) &&
|
||||
extract_rs1(addi4) == extract_rd(slli3) &&
|
||||
extract_rs1(addi4) == extract_rd(addi4);
|
||||
}
|
||||
|
||||
// the instruction sequence of li16u is as below:
|
||||
// lui
|
||||
// srli
|
||||
@@ -1754,7 +1719,6 @@ private:
|
||||
}
|
||||
|
||||
static bool is_li32_at(address instr);
|
||||
static bool is_li64_at(address instr);
|
||||
static bool is_pc_relative_at(address branch);
|
||||
|
||||
static bool is_membar(address addr) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "classfile/vmClasses.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterRuntime.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
@@ -37,7 +38,7 @@
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
|
||||
#define __ _masm->
|
||||
#define __ Disassembler::hook<MacroAssembler>(__FILE__, __LINE__, _masm)->
|
||||
|
||||
#ifdef PRODUCT
|
||||
#define BLOCK_COMMENT(str) /* nothing */
|
||||
|
||||
@@ -68,10 +68,10 @@ address NativeCall::destination() const {
|
||||
// Used in the runtime linkage of calls; see class CompiledIC.
|
||||
//
|
||||
// Add parameter assert_lock to switch off assertion
|
||||
// during code generation, where no patching lock is needed.
|
||||
// during code generation, where no lock is needed.
|
||||
void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) {
|
||||
assert(!assert_lock ||
|
||||
(Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
|
||||
(CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) ||
|
||||
CompiledICLocker::is_safe(addr_at(0)),
|
||||
"concurrent code patching");
|
||||
|
||||
|
||||
@@ -84,8 +84,8 @@ reg_def R0 ( NS, NS, Op_RegI, 0, x0->as_VMReg() ); // zr
|
||||
reg_def R0_H ( NS, NS, Op_RegI, 0, x0->as_VMReg()->next() );
|
||||
reg_def R1 ( NS, SOC, Op_RegI, 1, x1->as_VMReg() ); // ra
|
||||
reg_def R1_H ( NS, SOC, Op_RegI, 1, x1->as_VMReg()->next() );
|
||||
reg_def R2 ( NS, SOE, Op_RegI, 2, x2->as_VMReg() ); // sp
|
||||
reg_def R2_H ( NS, SOE, Op_RegI, 2, x2->as_VMReg()->next() );
|
||||
reg_def R2 ( NS, NS, Op_RegI, 2, x2->as_VMReg() ); // sp
|
||||
reg_def R2_H ( NS, NS, Op_RegI, 2, x2->as_VMReg()->next() );
|
||||
reg_def R3 ( NS, NS, Op_RegI, 3, x3->as_VMReg() ); // gp
|
||||
reg_def R3_H ( NS, NS, Op_RegI, 3, x3->as_VMReg()->next() );
|
||||
reg_def R4 ( NS, NS, Op_RegI, 4, x4->as_VMReg() ); // tp
|
||||
|
||||
@@ -4795,36 +4795,49 @@ instruct vcountTrailingZeros(vReg dst, vReg src) %{
|
||||
|
||||
// ------------------------------ Vector Load Gather ---------------------------
|
||||
|
||||
instruct gather_load(vReg dst, indirect mem, vReg idx) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 4 ||
|
||||
type2aelembytes(Matcher::vector_element_basic_type(n)) == 8);
|
||||
instruct gather_loadS(vReg dst, indirect mem, vReg idx) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 4);
|
||||
match(Set dst (LoadVectorGather mem idx));
|
||||
effect(TEMP_DEF dst);
|
||||
format %{ "gather_load $dst, $mem, $idx" %}
|
||||
format %{ "gather_loadS $dst, $mem, $idx" %}
|
||||
ins_encode %{
|
||||
__ vmv1r_v(as_VectorRegister($dst$$reg), as_VectorRegister($idx$$reg));
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), (int)sew);
|
||||
__ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($idx$$reg), (int)sew);
|
||||
__ vluxei32_v(as_VectorRegister($dst$$reg), as_Register($mem$$base),
|
||||
as_VectorRegister($dst$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct gather_load_masked(vReg dst, indirect mem, vReg idx, vRegMask_V0 v0, vReg tmp) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 4 ||
|
||||
type2aelembytes(Matcher::vector_element_basic_type(n)) == 8);
|
||||
match(Set dst (LoadVectorGatherMasked mem (Binary idx v0)));
|
||||
effect(TEMP_DEF dst, TEMP tmp);
|
||||
format %{ "gather_load_masked $dst, $mem, $idx, $v0\t# KILL $tmp" %}
|
||||
instruct gather_loadD(vReg dst, indirect mem, vReg idx) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 8);
|
||||
match(Set dst (LoadVectorGather mem idx));
|
||||
effect(TEMP_DEF dst);
|
||||
format %{ "gather_loadD $dst, $mem, $idx" %}
|
||||
ins_encode %{
|
||||
__ vmv1r_v(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg));
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), (int)sew);
|
||||
__ vzext_vf2(as_VectorRegister($dst$$reg), as_VectorRegister($idx$$reg));
|
||||
__ vsll_vi(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg), (int)sew);
|
||||
__ vluxei64_v(as_VectorRegister($dst$$reg), as_Register($mem$$base),
|
||||
as_VectorRegister($dst$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct gather_loadS_masked(vReg dst, indirect mem, vReg idx, vRegMask_V0 v0, vReg tmp) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 4);
|
||||
match(Set dst (LoadVectorGatherMasked mem (Binary idx v0)));
|
||||
effect(TEMP_DEF dst, TEMP tmp);
|
||||
format %{ "gather_loadS_masked $dst, $mem, $idx, $v0\t# KILL $tmp" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg), (int)sew);
|
||||
__ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg),
|
||||
as_VectorRegister($dst$$reg));
|
||||
__ vluxei32_v(as_VectorRegister($dst$$reg), as_Register($mem$$base),
|
||||
@@ -4833,44 +4846,93 @@ instruct gather_load_masked(vReg dst, indirect mem, vReg idx, vRegMask_V0 v0, vR
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct gather_loadD_masked(vReg dst, indirect mem, vReg idx, vRegMask_V0 v0, vReg tmp) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n)) == 8);
|
||||
match(Set dst (LoadVectorGatherMasked mem (Binary idx v0)));
|
||||
effect(TEMP_DEF dst, TEMP tmp);
|
||||
format %{ "gather_loadD_masked $dst, $mem, $idx, $v0\t# KILL $tmp" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this);
|
||||
Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this));
|
||||
__ vzext_vf2(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg));
|
||||
__ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), (int)sew);
|
||||
__ vxor_vv(as_VectorRegister($dst$$reg), as_VectorRegister($dst$$reg),
|
||||
as_VectorRegister($dst$$reg));
|
||||
__ vluxei64_v(as_VectorRegister($dst$$reg), as_Register($mem$$base),
|
||||
as_VectorRegister($tmp$$reg), Assembler::v0_t);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// ------------------------------ Vector Store Scatter -------------------------
|
||||
|
||||
instruct scatter_store(indirect mem, vReg src, vReg idx, vReg tmp) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 4 ||
|
||||
type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 8);
|
||||
instruct scatter_storeS(indirect mem, vReg src, vReg idx, vReg tmp) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 4);
|
||||
match(Set mem (StoreVectorScatter mem (Binary src idx)));
|
||||
effect(TEMP tmp);
|
||||
format %{ "scatter_store $mem, $idx, $src\t# KILL $tmp" %}
|
||||
format %{ "scatter_storeS $mem, $idx, $src\t# KILL $tmp" %}
|
||||
ins_encode %{
|
||||
__ vmv1r_v(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg));
|
||||
BasicType bt = Matcher::vector_element_basic_type(this, $src);
|
||||
Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this, $src));
|
||||
__ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), (int)sew);
|
||||
__ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg), (int)sew);
|
||||
__ vsuxei32_v(as_VectorRegister($src$$reg), as_Register($mem$$base),
|
||||
as_VectorRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct scatter_store_masked(indirect mem, vReg src, vReg idx, vRegMask_V0 v0, vReg tmp) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 4 ||
|
||||
type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 8);
|
||||
match(Set mem (StoreVectorScatterMasked mem (Binary src (Binary idx v0))));
|
||||
instruct scatter_storeD(indirect mem, vReg src, vReg idx, vReg tmp) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 8);
|
||||
match(Set mem (StoreVectorScatter mem (Binary src idx)));
|
||||
effect(TEMP tmp);
|
||||
format %{ "scatter_store_masked $mem, $idx, $src, $v0\t# KILL $tmp" %}
|
||||
format %{ "scatter_storeD $mem, $idx, $src\t# KILL $tmp" %}
|
||||
ins_encode %{
|
||||
__ vmv1r_v(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg));
|
||||
BasicType bt = Matcher::vector_element_basic_type(this, $src);
|
||||
Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this, $src));
|
||||
__ vzext_vf2(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg));
|
||||
__ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), (int)sew);
|
||||
__ vsuxei64_v(as_VectorRegister($src$$reg), as_Register($mem$$base),
|
||||
as_VectorRegister($tmp$$reg));
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct scatter_storeS_masked(indirect mem, vReg src, vReg idx, vRegMask_V0 v0, vReg tmp) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 4);
|
||||
match(Set mem (StoreVectorScatterMasked mem (Binary src (Binary idx v0))));
|
||||
effect(TEMP tmp);
|
||||
format %{ "scatter_storeS_masked $mem, $idx, $src, $v0\t# KILL $tmp" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this, $src);
|
||||
Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this, $src));
|
||||
__ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg), (int)sew);
|
||||
__ vsuxei32_v(as_VectorRegister($src$$reg), as_Register($mem$$base),
|
||||
as_VectorRegister($tmp$$reg), Assembler::v0_t);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct scatter_storeD_masked(indirect mem, vReg src, vReg idx, vRegMask_V0 v0, vReg tmp) %{
|
||||
predicate(type2aelembytes(Matcher::vector_element_basic_type(n->in(3)->in(1))) == 8);
|
||||
match(Set mem (StoreVectorScatterMasked mem (Binary src (Binary idx v0))));
|
||||
effect(TEMP tmp);
|
||||
format %{ "scatter_storeD_masked $mem, $idx, $src, $v0\t# KILL $tmp" %}
|
||||
ins_encode %{
|
||||
BasicType bt = Matcher::vector_element_basic_type(this, $src);
|
||||
Assembler::SEW sew = Assembler::elemtype_to_sew(bt);
|
||||
__ vsetvli_helper(bt, Matcher::vector_length(this, $src));
|
||||
__ vzext_vf2(as_VectorRegister($tmp$$reg), as_VectorRegister($idx$$reg));
|
||||
__ vsll_vi(as_VectorRegister($tmp$$reg), as_VectorRegister($tmp$$reg), (int)sew);
|
||||
__ vsuxei64_v(as_VectorRegister($src$$reg), as_Register($mem$$base),
|
||||
as_VectorRegister($tmp$$reg), Assembler::v0_t);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// ------------------------------ Populate Index to a Vector -------------------
|
||||
|
||||
instruct populateindex(vReg dst, iRegIorL2I src1, iRegIorL2I src2, vReg tmp) %{
|
||||
|
||||
@@ -30,8 +30,15 @@
|
||||
|
||||
// Java frames don't have callee saved registers (except for fp), so we can use a smaller RegisterMap
|
||||
class SmallRegisterMap {
|
||||
constexpr SmallRegisterMap() = default;
|
||||
~SmallRegisterMap() = default;
|
||||
NONCOPYABLE(SmallRegisterMap);
|
||||
|
||||
public:
|
||||
static constexpr SmallRegisterMap* instance = nullptr;
|
||||
static const SmallRegisterMap* instance() {
|
||||
static constexpr SmallRegisterMap the_instance{};
|
||||
return &the_instance;
|
||||
}
|
||||
private:
|
||||
static void assert_is_fp(VMReg r) NOT_DEBUG_RETURN
|
||||
DEBUG_ONLY({ assert (r == fp->as_VMReg() || r == fp->as_VMReg()->next(), "Reg: %s", r->name()); })
|
||||
@@ -48,17 +55,6 @@ public:
|
||||
return map;
|
||||
}
|
||||
|
||||
SmallRegisterMap() {}
|
||||
|
||||
SmallRegisterMap(const RegisterMap* map) {
|
||||
#ifdef ASSERT
|
||||
for(int i = 0; i < RegisterMap::reg_count; i++) {
|
||||
VMReg r = VMRegImpl::as_VMReg(i);
|
||||
if (map->location(r, (intptr_t*)nullptr) != nullptr) assert_is_fp(r);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline address location(VMReg reg, intptr_t* sp) const {
|
||||
assert_is_fp(reg);
|
||||
return (address)(sp - 2);
|
||||
|
||||
@@ -5374,6 +5374,29 @@ static const int64_t right_3_bits = right_n_bits(3);
|
||||
return start;
|
||||
}
|
||||
|
||||
// load Method* target of MethodHandle
|
||||
// j_rarg0 = jobject receiver
|
||||
// xmethod = Method* result
|
||||
address generate_upcall_stub_load_target() {
|
||||
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target");
|
||||
address start = __ pc();
|
||||
|
||||
__ resolve_global_jobject(j_rarg0, t0, t1);
|
||||
// Load target method from receiver
|
||||
__ load_heap_oop(xmethod, Address(j_rarg0, java_lang_invoke_MethodHandle::form_offset()), t0, t1);
|
||||
__ load_heap_oop(xmethod, Address(xmethod, java_lang_invoke_LambdaForm::vmentry_offset()), t0, t1);
|
||||
__ load_heap_oop(xmethod, Address(xmethod, java_lang_invoke_MemberName::method_offset()), t0, t1);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, xmethod,
|
||||
Address(xmethod, java_lang_invoke_ResolvedMethodName::vmtarget_offset()),
|
||||
noreg, noreg);
|
||||
__ sd(xmethod, Address(xthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
|
||||
|
||||
__ ret();
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Continuation point for throwing of implicit exceptions that are
|
||||
// not handled in the current activation. Fabricates an exception
|
||||
// oop and initiates normal exception dispatching in this
|
||||
@@ -5567,6 +5590,7 @@ static const int64_t right_3_bits = right_n_bits(3);
|
||||
}
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target();
|
||||
|
||||
StubRoutines::riscv::set_completed();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "gc/shared/barrierSetAssembler.hpp"
|
||||
#include "interpreter/bytecodeHistogram.hpp"
|
||||
#include "interpreter/bytecodeTracer.hpp"
|
||||
@@ -70,7 +71,7 @@
|
||||
// Max size with JVMTI
|
||||
int TemplateInterpreter::InterpreterCodeSize = 256 * 1024;
|
||||
|
||||
#define __ _masm->
|
||||
#define __ Disassembler::hook<InterpreterMacroAssembler>(__FILE__, __LINE__, _masm)->
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1748,13 +1749,21 @@ void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t,
|
||||
address& vep) {
|
||||
assert(t != nullptr && t->is_valid() && t->tos_in() == vtos, "illegal template");
|
||||
Label L;
|
||||
aep = __ pc(); __ push_ptr(); __ j(L);
|
||||
fep = __ pc(); __ push_f(); __ j(L);
|
||||
dep = __ pc(); __ push_d(); __ j(L);
|
||||
lep = __ pc(); __ push_l(); __ j(L);
|
||||
bep = cep = sep =
|
||||
iep = __ pc(); __ push_i();
|
||||
vep = __ pc();
|
||||
aep = __ pc(); // atos entry point
|
||||
__ push_ptr();
|
||||
__ j(L);
|
||||
fep = __ pc(); // ftos entry point
|
||||
__ push_f();
|
||||
__ j(L);
|
||||
dep = __ pc(); // dtos entry point
|
||||
__ push_d();
|
||||
__ j(L);
|
||||
lep = __ pc(); // ltos entry point
|
||||
__ push_l();
|
||||
__ j(L);
|
||||
bep = cep = sep = iep = __ pc(); // [bcsi]tos entry point
|
||||
__ push_i();
|
||||
vep = __ pc(); // vtos entry point
|
||||
__ bind(L);
|
||||
generate_and_dispatch(t);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "gc/shared/barrierSetAssembler.hpp"
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
#include "gc/shared/tlab_globals.hpp"
|
||||
@@ -49,7 +50,7 @@
|
||||
#include "runtime/synchronizer.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
|
||||
#define __ _masm->
|
||||
#define __ Disassembler::hook<InterpreterMacroAssembler>(__FILE__, __LINE__, _masm)->
|
||||
|
||||
// Address computation: local variables
|
||||
|
||||
@@ -178,7 +179,6 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
|
||||
__ la(temp_reg, Address(temp_reg, in_bytes(ResolvedFieldEntry::put_code_offset())));
|
||||
}
|
||||
// Load-acquire the bytecode to match store-release in ResolvedFieldEntry::fill_in()
|
||||
__ membar(MacroAssembler::AnyAny);
|
||||
__ lbu(temp_reg, Address(temp_reg, 0));
|
||||
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
|
||||
__ mv(bc_reg, bc);
|
||||
@@ -320,7 +320,6 @@ void TemplateTable::ldc(LdcType type) {
|
||||
// get type
|
||||
__ addi(x13, x11, tags_offset);
|
||||
__ add(x13, x10, x13);
|
||||
__ membar(MacroAssembler::AnyAny);
|
||||
__ lbu(x13, Address(x13, 0));
|
||||
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
|
||||
|
||||
@@ -2189,7 +2188,6 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no,
|
||||
break;
|
||||
}
|
||||
// Load-acquire the bytecode to match store-release in InterpreterRuntime
|
||||
__ membar(MacroAssembler::AnyAny);
|
||||
__ lbu(temp, Address(temp, 0));
|
||||
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
|
||||
|
||||
@@ -2241,7 +2239,6 @@ void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
|
||||
__ la(temp, Address(Rcache, in_bytes(ResolvedFieldEntry::put_code_offset())));
|
||||
}
|
||||
// Load-acquire the bytecode to match store-release in ResolvedFieldEntry::fill_in()
|
||||
__ membar(MacroAssembler::AnyAny);
|
||||
__ lbu(temp, Address(temp, 0));
|
||||
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
|
||||
__ mv(t0, (int) code); // have we resolved this bytecode?
|
||||
@@ -2403,7 +2400,6 @@ void TemplateTable::load_invokedynamic_entry(Register method) {
|
||||
Label resolved;
|
||||
|
||||
__ load_resolved_indy_entry(cache, index);
|
||||
__ membar(MacroAssembler::AnyAny);
|
||||
__ ld(method, Address(cache, in_bytes(ResolvedIndyEntry::method_offset())));
|
||||
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
|
||||
|
||||
@@ -2418,7 +2414,6 @@ void TemplateTable::load_invokedynamic_entry(Register method) {
|
||||
__ call_VM(noreg, entry, method);
|
||||
// Update registers with resolved info
|
||||
__ load_resolved_indy_entry(cache, index);
|
||||
__ membar(MacroAssembler::AnyAny);
|
||||
__ ld(method, Address(cache, in_bytes(ResolvedIndyEntry::method_offset())));
|
||||
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
|
||||
|
||||
@@ -3533,7 +3528,6 @@ void TemplateTable::_new() {
|
||||
const int tags_offset = Array<u1>::base_offset_in_bytes();
|
||||
__ add(t0, x10, x13);
|
||||
__ la(t0, Address(t0, tags_offset));
|
||||
__ membar(MacroAssembler::AnyAny);
|
||||
__ lbu(t0, t0);
|
||||
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
|
||||
__ sub(t1, t0, (u1)JVM_CONSTANT_Class);
|
||||
@@ -3652,7 +3646,6 @@ void TemplateTable::checkcast() {
|
||||
// See if bytecode has already been quicked
|
||||
__ add(t0, x13, Array<u1>::base_offset_in_bytes());
|
||||
__ add(x11, t0, x9);
|
||||
__ membar(MacroAssembler::AnyAny);
|
||||
__ lbu(x11, x11);
|
||||
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
|
||||
__ sub(t0, x11, (u1)JVM_CONSTANT_Class);
|
||||
@@ -3708,7 +3701,6 @@ void TemplateTable::instanceof() {
|
||||
// See if bytecode has already been quicked
|
||||
__ add(t0, x13, Array<u1>::base_offset_in_bytes());
|
||||
__ add(x11, t0, x9);
|
||||
__ membar(MacroAssembler::AnyAny);
|
||||
__ lbu(x11, x11);
|
||||
__ membar(MacroAssembler::LoadLoad | MacroAssembler::LoadStore);
|
||||
__ sub(t0, x11, (u1)JVM_CONSTANT_Class);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
@@ -117,7 +118,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
static const int upcall_stub_code_base_size = 1024;
|
||||
static const int upcall_stub_size_per_arg = 16;
|
||||
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
|
||||
BasicType* out_sig_bt, int total_out_args,
|
||||
BasicType ret_type,
|
||||
jobject jabi, jobject jconv,
|
||||
@@ -223,7 +224,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
__ block_comment("{ on_entry");
|
||||
__ la(c_rarg0, Address(sp, frame_data_offset));
|
||||
__ movptr(c_rarg1, (address) receiver);
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, UpcallLinker::on_entry));
|
||||
__ mv(xthread, x10);
|
||||
__ reinit_heapbase();
|
||||
@@ -260,12 +260,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
arg_shuffle.generate(_masm, as_VMStorage(shuffle_reg), abi._shadow_space_bytes, 0);
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
__ block_comment("{ receiver ");
|
||||
__ get_vm_result(j_rarg0, xthread);
|
||||
__ block_comment("} receiver ");
|
||||
|
||||
__ mov_metadata(xmethod, entry);
|
||||
__ sd(xmethod, Address(xthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
|
||||
__ block_comment("{ load target ");
|
||||
__ movptr(j_rarg0, (address) receiver);
|
||||
__ far_call(RuntimeAddress(StubRoutines::upcall_stub_load_target())); // loads Method* into xmethod
|
||||
__ block_comment("} load target ");
|
||||
|
||||
__ push_cont_fastpath(xthread);
|
||||
|
||||
@@ -338,7 +336,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
#ifndef PRODUCT
|
||||
stringStream ss;
|
||||
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
|
||||
ss.print("upcall_stub_%s", signature->as_C_string());
|
||||
const char *name = _masm->code_string(ss.as_string());
|
||||
#else // PRODUCT
|
||||
const char* name = "upcall_stub";
|
||||
|
||||
@@ -131,9 +131,19 @@ void LIR_Assembler::osr_entry() {
|
||||
// copied into place by code emitted in the IR.
|
||||
|
||||
Register OSR_buf = osrBufferPointer()->as_register();
|
||||
{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
|
||||
int monitor_offset = BytesPerWord * method()->max_locals() +
|
||||
(2 * BytesPerWord) * (number_of_locks - 1);
|
||||
{
|
||||
assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
|
||||
|
||||
const int locals_space = BytesPerWord * method() -> max_locals();
|
||||
int monitor_offset = locals_space + (2 * BytesPerWord) * (number_of_locks - 1);
|
||||
bool large_offset = !Immediate::is_simm20(monitor_offset + BytesPerWord) && number_of_locks > 0;
|
||||
|
||||
if (large_offset) {
|
||||
// z_lg can only handle displacement upto 20bit signed binary integer
|
||||
__ z_algfi(OSR_buf, locals_space);
|
||||
monitor_offset -= locals_space;
|
||||
}
|
||||
|
||||
// SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
|
||||
// the OSR buffer using 2 word entries: first the lock and then
|
||||
// the oop.
|
||||
@@ -147,6 +157,10 @@ void LIR_Assembler::osr_entry() {
|
||||
__ z_lg(Z_R1_scratch, slot_offset + 1*BytesPerWord, OSR_buf);
|
||||
__ z_stg(Z_R1_scratch, frame_map()->address_for_monitor_object(i));
|
||||
}
|
||||
|
||||
if (large_offset) {
|
||||
__ z_slgfi(OSR_buf, locals_space);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,16 +105,60 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators
|
||||
}
|
||||
}
|
||||
|
||||
// Generic implementation. GCs can provide an optimized one.
|
||||
void BarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2) {
|
||||
NearLabel Ldone;
|
||||
__ z_ltgr(tmp1, value);
|
||||
__ z_bre(Ldone); // Use null result as-is.
|
||||
|
||||
__ z_nill(value, ~JNIHandles::tag_mask);
|
||||
__ z_lg(value, 0, value); // Resolve (untagged) jobject.
|
||||
assert_different_registers(value, tmp1, tmp2);
|
||||
NearLabel done, weak_tag, verify, tagged;
|
||||
__ z_ltgr(value, value);
|
||||
__ z_bre(done); // Use null result as-is.
|
||||
|
||||
__ z_tmll(value, JNIHandles::tag_mask);
|
||||
__ z_btrue(tagged); // not zero
|
||||
|
||||
// Resolve Local handle
|
||||
__ access_load_at(T_OBJECT, IN_NATIVE | AS_RAW, Address(value, 0), value, tmp1, tmp2);
|
||||
__ z_bru(verify);
|
||||
|
||||
__ bind(tagged);
|
||||
__ testbit(value, exact_log2(JNIHandles::TypeTag::weak_global)); // test for weak tag
|
||||
__ z_btrue(weak_tag);
|
||||
|
||||
// resolve global handle
|
||||
__ access_load_at(T_OBJECT, IN_NATIVE, Address(value, -JNIHandles::TypeTag::global), value, tmp1, tmp2);
|
||||
__ z_bru(verify);
|
||||
|
||||
__ bind(weak_tag);
|
||||
// resolve jweak.
|
||||
__ access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
|
||||
Address(value, -JNIHandles::TypeTag::weak_global), value, tmp1, tmp2);
|
||||
__ bind(verify);
|
||||
__ verify_oop(value, FILE_AND_LINE);
|
||||
__ bind(Ldone);
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
// Generic implementation. GCs can provide an optimized one.
|
||||
void BarrierSetAssembler::resolve_global_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2) {
|
||||
assert_different_registers(value, tmp1, tmp2);
|
||||
NearLabel done;
|
||||
|
||||
__ z_ltgr(value, value);
|
||||
__ z_bre(done); // use null as-is.
|
||||
|
||||
#ifdef ASSERT
|
||||
{
|
||||
NearLabel valid_global_tag;
|
||||
__ testbit(value, exact_log2(JNIHandles::TypeTag::global)); // test for global tag
|
||||
__ z_btrue(valid_global_tag);
|
||||
__ stop("non global jobject using resolve_global_jobject");
|
||||
__ bind(valid_global_tag);
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
||||
// Resolve global handle
|
||||
__ access_load_at(T_OBJECT, IN_NATIVE, Address(value, -JNIHandles::TypeTag::global), value, tmp1, tmp2);
|
||||
__ verify_oop(value, FILE_AND_LINE);
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
const Address& addr, Register val, Register tmp1, Register tmp2, Register tmp3);
|
||||
|
||||
virtual void resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2);
|
||||
virtual void resolve_global_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2);
|
||||
|
||||
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
|
||||
Register obj, Register tmp, Label& slowpath);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2019 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2024 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "gc/shared/modRefBarrierSetAssembler.hpp"
|
||||
#include "runtime/jniHandles.hpp"
|
||||
|
||||
#define __ masm->
|
||||
|
||||
@@ -58,3 +59,16 @@ void ModRefBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet deco
|
||||
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);
|
||||
}
|
||||
}
|
||||
|
||||
void ModRefBarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2) {
|
||||
NearLabel done;
|
||||
|
||||
__ z_ltgr(value, value);
|
||||
__ z_bre(done); // use null as-is.
|
||||
|
||||
__ z_nill(value, ~JNIHandles::tag_mask);
|
||||
__ z_lg(value, 0, value); // Resolve (untagged) jobject.
|
||||
|
||||
__ verify_oop(value, FILE_AND_LINE);
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2024 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -48,6 +48,8 @@ public:
|
||||
|
||||
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
const Address& dst, Register val, Register tmp1, Register tmp2, Register tmp3);
|
||||
|
||||
virtual void resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2);
|
||||
};
|
||||
|
||||
#endif // CPU_S390_GC_SHARED_MODREFBARRIERSETASSEMBLER_S390_HPP
|
||||
|
||||
@@ -3380,6 +3380,11 @@ void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp
|
||||
bs->resolve_jobject(this, value, tmp1, tmp2);
|
||||
}
|
||||
|
||||
void MacroAssembler::resolve_global_jobject(Register value, Register tmp1, Register tmp2) {
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->resolve_global_jobject(this, value, tmp1, tmp2);
|
||||
}
|
||||
|
||||
// Last_Java_sp must comply to the rules in frame_s390.hpp.
|
||||
void MacroAssembler::set_last_Java_frame(Register last_Java_sp, Register last_Java_pc, bool allow_relocation) {
|
||||
BLOCK_COMMENT("set_last_Java_frame {");
|
||||
|
||||
@@ -730,6 +730,7 @@ class MacroAssembler: public Assembler {
|
||||
void lightweight_unlock(Register obj, Register hdr, Register tmp, Label& slow);
|
||||
|
||||
void resolve_jobject(Register value, Register tmp1, Register tmp2);
|
||||
void resolve_global_jobject(Register value, Register tmp1, Register tmp2);
|
||||
|
||||
// Support for last Java frame (but use call_VM instead where possible).
|
||||
private:
|
||||
@@ -791,7 +792,6 @@ class MacroAssembler: public Assembler {
|
||||
void compare_klass_ptr(Register Rop1, int64_t disp, Register Rbase, bool maybenull);
|
||||
|
||||
// Access heap oop, handle encoding and GC barriers.
|
||||
private:
|
||||
void access_store_at(BasicType type, DecoratorSet decorators,
|
||||
const Address& addr, Register val,
|
||||
Register tmp1, Register tmp2, Register tmp3);
|
||||
|
||||
@@ -658,8 +658,8 @@ void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
|
||||
|
||||
void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
|
||||
assert(((intptr_t)instr_addr & (BytesPerWord-1)) == 0, "requirement for mt safe patching");
|
||||
// Bytes_after_jump cannot change, because we own the Patching_lock.
|
||||
assert(Patching_lock->owned_by_self(), "must hold lock to patch instruction");
|
||||
// Bytes_after_jump cannot change, because we own the CodeCache_lock.
|
||||
assert(CodeCache_lock->owned_by_self(), "must hold lock to patch instruction");
|
||||
intptr_t bytes_after_jump = (*(intptr_t*)instr_addr) & 0x000000000000ffffL; // 2 bytes after jump.
|
||||
intptr_t load_const_bytes = (*(intptr_t*)code_buffer) & 0xffffffffffff0000L;
|
||||
*(intptr_t*)instr_addr = load_const_bytes | bytes_after_jump;
|
||||
|
||||
@@ -30,8 +30,15 @@
|
||||
|
||||
// Java frames don't have callee saved registers (except for rfp), so we can use a smaller RegisterMap
|
||||
class SmallRegisterMap {
|
||||
constexpr SmallRegisterMap() = default;
|
||||
~SmallRegisterMap() = default;
|
||||
NONCOPYABLE(SmallRegisterMap);
|
||||
|
||||
public:
|
||||
static constexpr SmallRegisterMap* instance = nullptr;
|
||||
static const SmallRegisterMap* instance() {
|
||||
static constexpr SmallRegisterMap the_instance{};
|
||||
return &the_instance;
|
||||
}
|
||||
private:
|
||||
static void assert_is_rfp(VMReg r) NOT_DEBUG_RETURN
|
||||
DEBUG_ONLY({ Unimplemented(); })
|
||||
@@ -46,12 +53,6 @@ public:
|
||||
return map;
|
||||
}
|
||||
|
||||
SmallRegisterMap() {}
|
||||
|
||||
SmallRegisterMap(const RegisterMap* map) {
|
||||
Unimplemented();
|
||||
}
|
||||
|
||||
inline address location(VMReg reg, intptr_t* sp) const {
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
|
||||
@@ -3107,6 +3107,29 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return start;
|
||||
}
|
||||
|
||||
// load Method* target of MethodHandle
|
||||
// Z_ARG1 = jobject receiver
|
||||
// Z_method = Method* result
|
||||
address generate_upcall_stub_load_target() {
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target");
|
||||
address start = __ pc();
|
||||
|
||||
__ resolve_global_jobject(Z_ARG1, Z_tmp_1, Z_tmp_2);
|
||||
// Load target method from receiver
|
||||
__ load_heap_oop(Z_method, Address(Z_ARG1, java_lang_invoke_MethodHandle::form_offset()),
|
||||
noreg, noreg, IS_NOT_NULL);
|
||||
__ load_heap_oop(Z_method, Address(Z_method, java_lang_invoke_LambdaForm::vmentry_offset()),
|
||||
noreg, noreg, IS_NOT_NULL);
|
||||
__ load_heap_oop(Z_method, Address(Z_method, java_lang_invoke_MemberName::method_offset()),
|
||||
noreg, noreg, IS_NOT_NULL);
|
||||
__ z_lg(Z_method, Address(Z_method, java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
|
||||
__ z_stg(Z_method, Address(Z_thread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
|
||||
|
||||
__ z_br(Z_R14);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
void generate_initial_stubs() {
|
||||
// Generates all stubs and initializes the entry points.
|
||||
|
||||
@@ -3188,6 +3211,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target();
|
||||
}
|
||||
|
||||
void generate_compiler_stubs() {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
@@ -116,7 +117,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
|
||||
static const int upcall_stub_code_base_size = 1024;
|
||||
static const int upcall_stub_size_per_arg = 16; // arg save & restore + move
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
|
||||
BasicType* out_sig_bt, int total_out_args,
|
||||
BasicType ret_type,
|
||||
jobject jabi, jobject jconv,
|
||||
@@ -206,7 +207,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
__ block_comment("on_entry {");
|
||||
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry));
|
||||
__ z_aghik(Z_ARG1, Z_SP, frame_data_offset);
|
||||
__ load_const_optimized(Z_ARG2, (intptr_t)receiver);
|
||||
__ call(call_target_address);
|
||||
__ z_lgr(Z_thread, Z_RET);
|
||||
__ block_comment("} on_entry");
|
||||
@@ -216,12 +216,11 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
arg_shuffle.generate(_masm, shuffle_reg, abi._shadow_space_bytes, frame::z_jit_out_preserve_size);
|
||||
__ block_comment("} argument_shuffle");
|
||||
|
||||
__ block_comment("receiver {");
|
||||
__ get_vm_result(Z_ARG1);
|
||||
__ block_comment("} receiver");
|
||||
|
||||
__ load_const_optimized(Z_method, (intptr_t)entry);
|
||||
__ z_stg(Z_method, Address(Z_thread, in_bytes(JavaThread::callee_target_offset())));
|
||||
__ block_comment("load_target {");
|
||||
__ load_const_optimized(Z_ARG1, (intptr_t)receiver);
|
||||
__ load_const_optimized(call_target_address, StubRoutines::upcall_stub_load_target());
|
||||
__ call(call_target_address); // load taget Method* into Z_method
|
||||
__ block_comment("} load_target");
|
||||
|
||||
__ z_lg(call_target_address, Address(Z_method, in_bytes(Method::from_compiled_offset())));
|
||||
__ call(call_target_address);
|
||||
@@ -274,7 +273,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
#ifndef PRODUCT
|
||||
stringStream ss;
|
||||
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
|
||||
ss.print("upcall_stub_%s", signature->as_C_string());
|
||||
const char* name = _masm->code_string(ss.as_string());
|
||||
#else // PRODUCT
|
||||
const char* name = "upcall_stub";
|
||||
|
||||
@@ -4940,9 +4940,8 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl
|
||||
|
||||
// The bitmap is full to bursting.
|
||||
// Implicit invariant: BITMAP_FULL implies (length > 0)
|
||||
assert(Klass::SECONDARY_SUPERS_BITMAP_FULL == ~uintx(0), "");
|
||||
cmpq(r_bitmap, (int32_t)-1); // sign-extends immediate to 64-bit value
|
||||
jcc(Assembler::equal, L_huge);
|
||||
cmpl(r_array_length, (int32_t)Klass::SECONDARY_SUPERS_TABLE_SIZE - 2);
|
||||
jcc(Assembler::greater, L_huge);
|
||||
|
||||
// NB! Our caller has checked bits 0 and 1 in the bitmap. The
|
||||
// current slot (at secondary_supers[r_array_index]) has not yet
|
||||
|
||||
@@ -218,7 +218,7 @@ void NativeCall::insert(address code_pos, address entry) {
|
||||
// (spinlock). Then patches the last byte, and then atomically replaces
|
||||
// the jmp's with the first 4 byte of the new instruction.
|
||||
void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
|
||||
assert(Patching_lock->is_locked() ||
|
||||
assert(CodeCache_lock->is_locked() ||
|
||||
SafepointSynchronize::is_at_safepoint(), "concurrent code patching");
|
||||
assert (instr_addr != nullptr, "illegal address for code patching");
|
||||
|
||||
@@ -281,7 +281,7 @@ void NativeCall::set_destination_mt_safe(address dest) {
|
||||
debug_only(verify());
|
||||
// Make sure patching code is locked. No two threads can patch at the same
|
||||
// time but one may be executing this code.
|
||||
assert(Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint() ||
|
||||
assert(CodeCache_lock->is_locked() || SafepointSynchronize::is_at_safepoint() ||
|
||||
CompiledICLocker::is_safe(instruction_address()), "concurrent code patching");
|
||||
// Both C1 and C2 should now be generating code which aligns the patched address
|
||||
// to be within a single cache line.
|
||||
|
||||
@@ -30,8 +30,16 @@
|
||||
|
||||
// Java frames don't have callee saved registers (except for rbp), so we can use a smaller RegisterMap
|
||||
class SmallRegisterMap {
|
||||
constexpr SmallRegisterMap() = default;
|
||||
~SmallRegisterMap() = default;
|
||||
NONCOPYABLE(SmallRegisterMap);
|
||||
|
||||
public:
|
||||
static constexpr SmallRegisterMap* instance = nullptr;
|
||||
static const SmallRegisterMap* instance() {
|
||||
static constexpr SmallRegisterMap the_instance{};
|
||||
return &the_instance;
|
||||
}
|
||||
|
||||
private:
|
||||
static void assert_is_rbp(VMReg r) NOT_DEBUG_RETURN
|
||||
DEBUG_ONLY({ assert(r == rbp->as_VMReg() || r == rbp->as_VMReg()->next(), "Reg: %s", r->name()); })
|
||||
@@ -48,17 +56,6 @@ public:
|
||||
return map;
|
||||
}
|
||||
|
||||
SmallRegisterMap() {}
|
||||
|
||||
SmallRegisterMap(const RegisterMap* map) {
|
||||
#ifdef ASSERT
|
||||
for(int i = 0; i < RegisterMap::reg_count; i++) {
|
||||
VMReg r = VMRegImpl::as_VMReg(i);
|
||||
if (map->location(r, (intptr_t*)nullptr) != nullptr) assert_is_rbp(r);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline address location(VMReg reg, intptr_t* sp) const {
|
||||
assert_is_rbp(reg);
|
||||
return (address)(sp - frame::sender_sp_offset);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/vmIntrinsics.hpp"
|
||||
#include "compiler/oopMap.hpp"
|
||||
#include "gc/shared/barrierSet.hpp"
|
||||
@@ -3988,6 +3989,28 @@ address StubGenerator::generate_upcall_stub_exception_handler() {
|
||||
return start;
|
||||
}
|
||||
|
||||
// load Method* target of MethodHandle
|
||||
// j_rarg0 = jobject receiver
|
||||
// rbx = result
|
||||
address StubGenerator::generate_upcall_stub_load_target() {
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target");
|
||||
address start = __ pc();
|
||||
|
||||
__ resolve_global_jobject(j_rarg0, r15_thread, rscratch1);
|
||||
// Load target method from receiver
|
||||
__ load_heap_oop(rbx, Address(j_rarg0, java_lang_invoke_MethodHandle::form_offset()), rscratch1);
|
||||
__ load_heap_oop(rbx, Address(rbx, java_lang_invoke_LambdaForm::vmentry_offset()), rscratch1);
|
||||
__ load_heap_oop(rbx, Address(rbx, java_lang_invoke_MemberName::method_offset()), rscratch1);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx,
|
||||
Address(rbx, java_lang_invoke_ResolvedMethodName::vmtarget_offset()),
|
||||
noreg, noreg);
|
||||
__ movptr(Address(r15_thread, JavaThread::callee_target_offset()), rbx); // just in case callee is deoptimized
|
||||
|
||||
__ ret(0);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
address StubGenerator::generate_lookup_secondary_supers_table_stub(u1 super_klass_index) {
|
||||
StubCodeMark mark(this, "StubRoutines", "lookup_secondary_supers_table");
|
||||
|
||||
@@ -4190,6 +4213,7 @@ void StubGenerator::generate_final_stubs() {
|
||||
}
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target();
|
||||
}
|
||||
|
||||
void StubGenerator::generate_compiler_stubs() {
|
||||
|
||||
@@ -615,6 +615,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
// shared exception handler for FFM upcall stubs
|
||||
address generate_upcall_stub_exception_handler();
|
||||
address generate_upcall_stub_load_target();
|
||||
|
||||
// Specialized stub implementations for UseSecondarySupersTable.
|
||||
address generate_lookup_secondary_supers_table_stub(u1 super_klass_index);
|
||||
|
||||
@@ -249,7 +249,6 @@ address StubGenerator::generate_intpoly_montgomeryMult_P256() {
|
||||
const Register tmp = r9;
|
||||
|
||||
montgomeryMultiply(aLimbs, bLimbs, rLimbs, tmp, _masm);
|
||||
__ mov64(rax, 0x1); // Return 1 (Fig. 5, Step 6 [1] skipped in montgomeryMultiply)
|
||||
|
||||
__ leave();
|
||||
__ ret(0);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
|
||||
BasicType* out_sig_bt, int total_out_args,
|
||||
BasicType ret_type,
|
||||
jobject jabi, jobject jconv,
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "code/codeBlob.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "code/codeBlob.hpp"
|
||||
#include "code/vmreg.inline.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
@@ -165,10 +165,10 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
__ block_comment("} restore_callee_saved_regs ");
|
||||
}
|
||||
|
||||
static const int upcall_stub_code_base_size = 1024;
|
||||
static const int upcall_stub_code_base_size = 1200;
|
||||
static const int upcall_stub_size_per_arg = 16;
|
||||
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
|
||||
BasicType* out_sig_bt, int total_out_args,
|
||||
BasicType ret_type,
|
||||
jobject jabi, jobject jconv,
|
||||
@@ -277,7 +277,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
__ block_comment("{ on_entry");
|
||||
__ vzeroupper();
|
||||
__ lea(c_rarg0, Address(rsp, frame_data_offset));
|
||||
__ movptr(c_rarg1, (intptr_t)receiver);
|
||||
// stack already aligned
|
||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, UpcallLinker::on_entry)));
|
||||
__ movptr(r15_thread, rax);
|
||||
@@ -293,12 +292,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
arg_shuffle.generate(_masm, shuffle_reg, abi._shadow_space_bytes, 0);
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
__ block_comment("{ receiver ");
|
||||
__ get_vm_result(j_rarg0, r15_thread);
|
||||
__ block_comment("} receiver ");
|
||||
|
||||
__ mov_metadata(rbx, entry);
|
||||
__ movptr(Address(r15_thread, JavaThread::callee_target_offset()), rbx); // just in case callee is deoptimized
|
||||
__ block_comment("{ load target ");
|
||||
__ movptr(j_rarg0, (intptr_t)receiver);
|
||||
__ call(RuntimeAddress(StubRoutines::upcall_stub_load_target())); // puts target Method* in rbx
|
||||
__ block_comment("} load target ");
|
||||
|
||||
__ push_cont_fastpath();
|
||||
|
||||
@@ -373,7 +370,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
#ifndef PRODUCT
|
||||
stringStream ss;
|
||||
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
|
||||
ss.print("upcall_stub_%s", signature->as_C_string());
|
||||
const char* name = _masm->code_string(ss.freeze());
|
||||
#else // PRODUCT
|
||||
const char* name = "upcall_stub";
|
||||
|
||||
@@ -30,8 +30,15 @@
|
||||
|
||||
// Java frames don't have callee saved registers (except for rfp), so we can use a smaller RegisterMap
|
||||
class SmallRegisterMap {
|
||||
constexpr SmallRegisterMap() = default;
|
||||
~SmallRegisterMap() = default;
|
||||
NONCOPYABLE(SmallRegisterMap);
|
||||
|
||||
public:
|
||||
static constexpr SmallRegisterMap* instance = nullptr;
|
||||
static const SmallRegisterMap* instance() {
|
||||
static constexpr SmallRegisterMap the_instance{};
|
||||
return &the_instance;
|
||||
}
|
||||
private:
|
||||
static void assert_is_rfp(VMReg r) NOT_DEBUG_RETURN
|
||||
DEBUG_ONLY({ Unimplemented(); })
|
||||
@@ -46,12 +53,6 @@ public:
|
||||
return map;
|
||||
}
|
||||
|
||||
SmallRegisterMap() {}
|
||||
|
||||
SmallRegisterMap(const RegisterMap* map) {
|
||||
Unimplemented();
|
||||
}
|
||||
|
||||
inline address location(VMReg reg, intptr_t* sp) const {
|
||||
Unimplemented();
|
||||
return nullptr;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
|
||||
address UpcallLinker::make_upcall_stub(jobject mh, Method* entry,
|
||||
address UpcallLinker::make_upcall_stub(jobject mh, Symbol* signature,
|
||||
BasicType* out_sig_bt, int total_out_args,
|
||||
BasicType ret_type,
|
||||
jobject jabi, jobject jconv,
|
||||
|
||||
@@ -314,7 +314,10 @@ static jlong host_free_swap() {
|
||||
}
|
||||
|
||||
jlong os::free_swap_space() {
|
||||
jlong host_free_swap_val = host_free_swap();
|
||||
// os::total_swap_space() might return the containerized limit which might be
|
||||
// less than host_free_swap(). The upper bound of free swap needs to be the lower of the two.
|
||||
jlong host_free_swap_val = MIN2(os::total_swap_space(), host_free_swap());
|
||||
assert(host_free_swap_val >= 0, "sysinfo failed?");
|
||||
if (OSContainer::is_containerized()) {
|
||||
jlong mem_swap_limit = OSContainer::memory_and_swap_limit_in_bytes();
|
||||
jlong mem_limit = OSContainer::memory_limit_in_bytes();
|
||||
|
||||
@@ -1934,7 +1934,10 @@ void os::win32::print_windows_version(outputStream* st) {
|
||||
// - 2016 GA 10/2016 build: 14393
|
||||
// - 2019 GA 11/2018 build: 17763
|
||||
// - 2022 GA 08/2021 build: 20348
|
||||
if (build_number > 20347) {
|
||||
// - 2025 Preview build : 26040
|
||||
if (build_number > 26039) {
|
||||
st->print("Server 2025");
|
||||
} else if (build_number > 20347) {
|
||||
st->print("Server 2022");
|
||||
} else if (build_number > 17762) {
|
||||
st->print("Server 2019");
|
||||
@@ -3440,7 +3443,8 @@ static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fi
|
||||
os::attempt_reserve_memory_at(aligned_base, size, false, flag);
|
||||
}
|
||||
|
||||
assert(aligned_base != nullptr, "Did not manage to re-map after %d attempts?", max_attempts);
|
||||
assert(aligned_base != nullptr,
|
||||
"Did not manage to re-map after %d attempts (size %zu, alignment %zu, file descriptor %d)", max_attempts, size, alignment, file_desc);
|
||||
|
||||
return aligned_base;
|
||||
}
|
||||
@@ -4067,6 +4071,39 @@ int os::win32::_build_minor = 0;
|
||||
bool os::win32::_processor_group_warning_displayed = false;
|
||||
bool os::win32::_job_object_processor_group_warning_displayed = false;
|
||||
|
||||
void getWindowsInstallationType(char* buffer, int bufferSize) {
|
||||
HKEY hKey;
|
||||
const char* subKey = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
|
||||
const char* valueName = "InstallationType";
|
||||
|
||||
DWORD valueLength = bufferSize;
|
||||
|
||||
// Initialize buffer with empty string
|
||||
buffer[0] = '\0';
|
||||
|
||||
// Open the registry key
|
||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
|
||||
// Return empty buffer if key cannot be opened
|
||||
return;
|
||||
}
|
||||
|
||||
// Query the value
|
||||
if (RegQueryValueExA(hKey, valueName, NULL, NULL, (LPBYTE)buffer, &valueLength) != ERROR_SUCCESS) {
|
||||
RegCloseKey(hKey);
|
||||
buffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
bool isNanoServer() {
|
||||
const int BUFFER_SIZE = 256;
|
||||
char installationType[BUFFER_SIZE];
|
||||
getWindowsInstallationType(installationType, BUFFER_SIZE);
|
||||
return (strcmp(installationType, "Nano Server") == 0);
|
||||
}
|
||||
|
||||
void os::win32::initialize_windows_version() {
|
||||
assert(_major_version == 0, "windows version already initialized.");
|
||||
|
||||
@@ -4084,7 +4121,13 @@ void os::win32::initialize_windows_version() {
|
||||
warning("Attempt to determine system directory failed: %s", buf_len != 0 ? error_msg_buffer : "<unknown error>");
|
||||
return;
|
||||
}
|
||||
strncat(kernel32_path, "\\kernel32.dll", MAX_PATH - ret);
|
||||
|
||||
if (isNanoServer()) {
|
||||
// On Windows Nanoserver the kernel32.dll is located in the forwarders subdirectory
|
||||
strncat(kernel32_path, "\\forwarders\\kernel32.dll", MAX_PATH - ret);
|
||||
} else {
|
||||
strncat(kernel32_path, "\\kernel32.dll", MAX_PATH - ret);
|
||||
}
|
||||
|
||||
DWORD version_size = GetFileVersionInfoSize(kernel32_path, nullptr);
|
||||
if (version_size == 0) {
|
||||
|
||||
@@ -135,10 +135,11 @@ CodeBuffer::~CodeBuffer() {
|
||||
// Previous incarnations of this buffer are held live, so that internal
|
||||
// addresses constructed before expansions will not be confused.
|
||||
cb->free_blob();
|
||||
// free any overflow storage
|
||||
delete cb->_overflow_arena;
|
||||
}
|
||||
|
||||
if (_overflow_arena != nullptr) {
|
||||
// free any overflow storage
|
||||
delete _overflow_arena;
|
||||
}
|
||||
if (_shared_trampoline_requests != nullptr) {
|
||||
delete _shared_trampoline_requests;
|
||||
}
|
||||
@@ -960,8 +961,6 @@ void CodeBuffer::take_over_code_from(CodeBuffer* cb) {
|
||||
CodeSection* this_sect = code_section(n);
|
||||
this_sect->take_over_code_from(cb_sect);
|
||||
}
|
||||
_overflow_arena = cb->_overflow_arena;
|
||||
cb->_overflow_arena = nullptr;
|
||||
// Make sure the old cb won't try to use it or free it.
|
||||
DEBUG_ONLY(cb->_blob = (BufferBlob*)badAddress);
|
||||
}
|
||||
|
||||
@@ -1389,6 +1389,11 @@ void GraphBuilder::jsr(int dest) {
|
||||
// If the bytecodes are strange (jumping out of a jsr block) then we
|
||||
// might end up trying to re-parse a block containing a jsr which
|
||||
// has already been activated. Watch for this case and bail out.
|
||||
if (next_bci() >= method()->code_size()) {
|
||||
// This can happen if the subroutine does not terminate with a ret,
|
||||
// effectively turning the jsr into a goto.
|
||||
BAILOUT("too-complicated jsr/ret structure");
|
||||
}
|
||||
for (ScopeData* cur_scope_data = scope_data();
|
||||
cur_scope_data != nullptr && cur_scope_data->parsing_jsr() && cur_scope_data->scope() == scope();
|
||||
cur_scope_data = cur_scope_data->parent()) {
|
||||
@@ -1563,7 +1568,7 @@ void GraphBuilder::method_return(Value x, bool ignore_return) {
|
||||
// The conditions for a memory barrier are described in Parse::do_exits().
|
||||
bool need_mem_bar = false;
|
||||
if (method()->name() == ciSymbols::object_initializer_name() &&
|
||||
(scope()->wrote_final() ||
|
||||
(scope()->wrote_final() || scope()->wrote_stable() ||
|
||||
(AlwaysSafeConstructors && scope()->wrote_fields()) ||
|
||||
(support_IRIW_for_not_multiple_copy_atomic_cpu && scope()->wrote_volatile()))) {
|
||||
need_mem_bar = true;
|
||||
@@ -1741,15 +1746,17 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
}
|
||||
}
|
||||
|
||||
if (field->is_final() && (code == Bytecodes::_putfield)) {
|
||||
scope()->set_wrote_final();
|
||||
}
|
||||
|
||||
if (code == Bytecodes::_putfield) {
|
||||
scope()->set_wrote_fields();
|
||||
if (field->is_volatile()) {
|
||||
scope()->set_wrote_volatile();
|
||||
}
|
||||
if (field->is_final()) {
|
||||
scope()->set_wrote_final();
|
||||
}
|
||||
if (field->is_stable()) {
|
||||
scope()->set_wrote_stable();
|
||||
}
|
||||
}
|
||||
|
||||
const int offset = !needs_patching ? field->offset_in_bytes() : -1;
|
||||
@@ -3731,6 +3738,9 @@ bool GraphBuilder::try_inline_intrinsics(ciMethod* callee, bool ignore_return) {
|
||||
bool GraphBuilder::try_inline_jsr(int jsr_dest_bci) {
|
||||
// Introduce a new callee continuation point - all Ret instructions
|
||||
// will be replaced with Gotos to this point.
|
||||
if (next_bci() >= method()->code_size()) {
|
||||
return false;
|
||||
}
|
||||
BlockBegin* cont = block_at(next_bci());
|
||||
assert(cont != nullptr, "continuation must exist (BlockListBuilder starts a new block after a jsr");
|
||||
|
||||
|
||||
@@ -146,6 +146,7 @@ IRScope::IRScope(Compilation* compilation, IRScope* caller, int caller_bci, ciMe
|
||||
_wrote_final = false;
|
||||
_wrote_fields = false;
|
||||
_wrote_volatile = false;
|
||||
_wrote_stable = false;
|
||||
_start = nullptr;
|
||||
|
||||
if (osr_bci != -1) {
|
||||
|
||||
@@ -149,6 +149,7 @@ class IRScope: public CompilationResourceObj {
|
||||
bool _wrote_final; // has written final field
|
||||
bool _wrote_fields; // has written fields
|
||||
bool _wrote_volatile; // has written volatile field
|
||||
bool _wrote_stable; // has written @Stable field
|
||||
BlockBegin* _start; // the start block, successsors are method entries
|
||||
|
||||
ResourceBitMap _requires_phi_function; // bit is set if phi functions at loop headers are necessary for a local variable
|
||||
@@ -187,6 +188,8 @@ class IRScope: public CompilationResourceObj {
|
||||
bool wrote_fields () const { return _wrote_fields; }
|
||||
void set_wrote_volatile() { _wrote_volatile = true; }
|
||||
bool wrote_volatile () const { return _wrote_volatile; }
|
||||
void set_wrote_stable() { _wrote_stable = true; }
|
||||
bool wrote_stable() const { return _wrote_stable; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -483,14 +483,14 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
|
||||
|
||||
if (c) {
|
||||
jint value = c->type()->as_IntConstant()->value();
|
||||
if (value != min_jint) {
|
||||
if (ao->op() == Bytecodes::_isub) {
|
||||
value = -value;
|
||||
}
|
||||
if (ao->op() == Bytecodes::_iadd) {
|
||||
base = java_add(base, value);
|
||||
last_integer = base;
|
||||
last_instruction = other;
|
||||
} else {
|
||||
assert(ao->op() == Bytecodes::_isub, "unexpected bytecode");
|
||||
base = java_subtract(base, value);
|
||||
}
|
||||
last_integer = base;
|
||||
last_instruction = other;
|
||||
index = other;
|
||||
} else {
|
||||
break;
|
||||
|
||||
@@ -880,7 +880,7 @@ static Klass* resolve_field_return_klass(const methodHandle& caller, int bci, TR
|
||||
// movl reg, [reg1 + <const>] (for field offsets)
|
||||
// jmp continue
|
||||
// <being_init offset> <bytes to copy> <bytes to skip>
|
||||
// patch_stub: jmp Runtim1::patch_code (through a runtime stub)
|
||||
// patch_stub: jmp Runtime1::patch_code (through a runtime stub)
|
||||
// jmp patch_site
|
||||
//
|
||||
// If the class is being initialized the patch body is rewritten and
|
||||
@@ -1096,7 +1096,7 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* current, Runtime1::StubID stub_
|
||||
// Now copy code back
|
||||
|
||||
{
|
||||
MutexLocker ml_patch (current, Patching_lock, Mutex::_no_safepoint_check_flag);
|
||||
MutexLocker ml_code (current, CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
//
|
||||
// Deoptimization may have happened while we waited for the lock.
|
||||
// In that case we don't bother to do any patching we just return
|
||||
@@ -1261,12 +1261,8 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* current, Runtime1::StubID stub_
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we are patching in a non-perm oop, make sure the nmethod
|
||||
// is on the right list.
|
||||
{
|
||||
MutexLocker ml_code (current, CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
// If we are patching in a non-perm oop, make sure the nmethod
|
||||
// is on the right list.
|
||||
nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
|
||||
guarantee(nm != nullptr, "only nmethods can contain non-perm oops");
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "memory/iterator.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "sanitizers/ub.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
|
||||
@@ -61,6 +62,7 @@ ptrdiff_t ArchiveHeapLoader::_mapped_heap_delta = 0;
|
||||
|
||||
// Every mapped region is offset by _mapped_heap_delta from its requested address.
|
||||
// See FileMapInfo::heap_region_requested_address().
|
||||
ATTRIBUTE_NO_UBSAN
|
||||
void ArchiveHeapLoader::init_mapped_heap_info(address mapped_heap_bottom, ptrdiff_t delta, int dumptime_oop_shift) {
|
||||
assert(!_mapped_heap_relocation_initialized, "only once");
|
||||
if (!UseCompressedOops) {
|
||||
|
||||
@@ -66,19 +66,17 @@
|
||||
|
||||
class CppVtableInfo {
|
||||
intptr_t _vtable_size;
|
||||
intptr_t _cloned_vtable[1];
|
||||
intptr_t _cloned_vtable[1]; // Pseudo flexible array member.
|
||||
static size_t cloned_vtable_offset() { return offset_of(CppVtableInfo, _cloned_vtable); }
|
||||
public:
|
||||
static int num_slots(int vtable_size) {
|
||||
return 1 + vtable_size; // Need to add the space occupied by _vtable_size;
|
||||
}
|
||||
int vtable_size() { return int(uintx(_vtable_size)); }
|
||||
void set_vtable_size(int n) { _vtable_size = intptr_t(n); }
|
||||
intptr_t* cloned_vtable() { return &_cloned_vtable[0]; }
|
||||
void zero() { memset(_cloned_vtable, 0, sizeof(intptr_t) * vtable_size()); }
|
||||
// Using _cloned_vtable[i] for i > 0 causes undefined behavior. We use address calculation instead.
|
||||
intptr_t* cloned_vtable() { return (intptr_t*)((char*)this + cloned_vtable_offset()); }
|
||||
void zero() { memset(cloned_vtable(), 0, sizeof(intptr_t) * vtable_size()); }
|
||||
// Returns the address of the next CppVtableInfo that can be placed immediately after this CppVtableInfo
|
||||
static size_t byte_size(int vtable_size) {
|
||||
CppVtableInfo i;
|
||||
return pointer_delta(&i._cloned_vtable[vtable_size], &i, sizeof(u1));
|
||||
return cloned_vtable_offset() + (sizeof(intptr_t) * vtable_size);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1672,7 +1672,10 @@ void ciEnv::dump_replay_data_helper(outputStream* out) {
|
||||
for (int i = 0; i < objects->length(); i++) {
|
||||
objects->at(i)->dump_replay_data(out);
|
||||
}
|
||||
dump_compile_data(out);
|
||||
|
||||
if (this->task() != nullptr) {
|
||||
dump_compile_data(out);
|
||||
}
|
||||
out->flush();
|
||||
}
|
||||
|
||||
|
||||
@@ -241,9 +241,14 @@ LockedClassesDo::~LockedClassesDo() {
|
||||
|
||||
|
||||
// Iterating over the CLDG needs to be locked because
|
||||
// unloading can remove entries concurrently soon.
|
||||
template <bool keep_alive = true>
|
||||
class ClassLoaderDataGraphIteratorBase : public StackObj {
|
||||
// unloading can remove entries concurrently.
|
||||
// This iterator does not keep the CLD alive.
|
||||
// Any CLD OopHandles (modules, mirrors, resolved refs)
|
||||
// resolved must be treated as no keepalive. And requires
|
||||
// that its CLD's holder is kept alive if they escape the
|
||||
// caller's safepoint or ClassLoaderDataGraph_lock
|
||||
// critical section.
|
||||
class ClassLoaderDataGraph::ClassLoaderDataGraphIterator : public StackObj {
|
||||
ClassLoaderData* _next;
|
||||
Thread* _thread;
|
||||
HandleMark _hm; // clean up handles when this is done.
|
||||
@@ -251,12 +256,8 @@ class ClassLoaderDataGraphIteratorBase : public StackObj {
|
||||
// unless verifying at a safepoint.
|
||||
|
||||
public:
|
||||
ClassLoaderDataGraphIteratorBase() : _next(ClassLoaderDataGraph::_head), _thread(Thread::current()), _hm(_thread) {
|
||||
if (keep_alive) {
|
||||
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
|
||||
} else {
|
||||
assert_at_safepoint();
|
||||
}
|
||||
ClassLoaderDataGraphIterator() : _next(ClassLoaderDataGraph::_head), _thread(Thread::current()), _hm(_thread) {
|
||||
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
|
||||
}
|
||||
|
||||
ClassLoaderData* get_next() {
|
||||
@@ -266,10 +267,6 @@ public:
|
||||
cld = cld->next();
|
||||
}
|
||||
if (cld != nullptr) {
|
||||
if (keep_alive) {
|
||||
// Keep cld that is being returned alive.
|
||||
Handle(_thread, cld->holder());
|
||||
}
|
||||
_next = cld->next();
|
||||
} else {
|
||||
_next = nullptr;
|
||||
@@ -278,9 +275,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
using ClassLoaderDataGraphIterator = ClassLoaderDataGraphIteratorBase<true /* keep_alive */>;
|
||||
using ClassLoaderDataGraphIteratorNoKeepAlive = ClassLoaderDataGraphIteratorBase<false /* keep_alive */>;
|
||||
|
||||
void ClassLoaderDataGraph::loaded_cld_do(CLDClosure* cl) {
|
||||
ClassLoaderDataGraphIterator iter;
|
||||
while (ClassLoaderData* cld = iter.get_next()) {
|
||||
@@ -288,13 +282,6 @@ void ClassLoaderDataGraph::loaded_cld_do(CLDClosure* cl) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::loaded_cld_do_no_keepalive(CLDClosure* cl) {
|
||||
ClassLoaderDataGraphIteratorNoKeepAlive iter;
|
||||
while (ClassLoaderData* cld = iter.get_next()) {
|
||||
cl->do_cld(cld);
|
||||
}
|
||||
}
|
||||
|
||||
// These functions assume that the caller has locked the ClassLoaderDataGraph_lock
|
||||
// if they are not calling the function from a safepoint.
|
||||
void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
|
||||
@@ -318,6 +305,16 @@ void ClassLoaderDataGraph::methods_do(void f(Method*)) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::modules_do_keepalive(void f(ModuleEntry*)) {
|
||||
assert_locked_or_safepoint(Module_lock);
|
||||
ClassLoaderDataGraphIterator iter;
|
||||
while (ClassLoaderData* cld = iter.get_next()) {
|
||||
// Keep the holder alive.
|
||||
(void)cld->holder();
|
||||
cld->modules_do(f);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::modules_do(void f(ModuleEntry*)) {
|
||||
assert_locked_or_safepoint(Module_lock);
|
||||
ClassLoaderDataGraphIterator iter;
|
||||
@@ -334,9 +331,11 @@ void ClassLoaderDataGraph::packages_do(void f(PackageEntry*)) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) {
|
||||
void ClassLoaderDataGraph::loaded_classes_do_keepalive(KlassClosure* klass_closure) {
|
||||
ClassLoaderDataGraphIterator iter;
|
||||
while (ClassLoaderData* cld = iter.get_next()) {
|
||||
// Keep the holder alive.
|
||||
(void)cld->holder();
|
||||
cld->loaded_classes_do(klass_closure);
|
||||
}
|
||||
}
|
||||
@@ -346,7 +345,7 @@ void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) {
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::verify_dictionary() {
|
||||
ClassLoaderDataGraphIteratorNoKeepAlive iter;
|
||||
ClassLoaderDataGraphIterator iter;
|
||||
while (ClassLoaderData* cld = iter.get_next()) {
|
||||
if (cld->dictionary() != nullptr) {
|
||||
cld->dictionary()->verify();
|
||||
@@ -354,26 +353,28 @@ void ClassLoaderDataGraph::verify_dictionary() {
|
||||
}
|
||||
}
|
||||
|
||||
#define FOR_ALL_DICTIONARY(X) ClassLoaderDataGraphIterator iter; \
|
||||
while (ClassLoaderData* X = iter.get_next()) \
|
||||
if (X->dictionary() != nullptr)
|
||||
|
||||
void ClassLoaderDataGraph::print_dictionary(outputStream* st) {
|
||||
FOR_ALL_DICTIONARY(cld) {
|
||||
st->print("Dictionary for ");
|
||||
cld->print_value_on(st);
|
||||
st->cr();
|
||||
cld->dictionary()->print_on(st);
|
||||
st->cr();
|
||||
ClassLoaderDataGraphIterator iter;
|
||||
while (ClassLoaderData *cld = iter.get_next()) {
|
||||
if (cld->dictionary() != nullptr) {
|
||||
st->print("Dictionary for ");
|
||||
cld->print_value_on(st);
|
||||
st->cr();
|
||||
cld->dictionary()->print_on(st);
|
||||
st->cr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::print_table_statistics(outputStream* st) {
|
||||
FOR_ALL_DICTIONARY(cld) {
|
||||
ResourceMark rm; // loader_name_and_id
|
||||
stringStream tempst;
|
||||
tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id());
|
||||
cld->dictionary()->print_table_statistics(st, tempst.freeze());
|
||||
ClassLoaderDataGraphIterator iter;
|
||||
while (ClassLoaderData *cld = iter.get_next()) {
|
||||
if (cld->dictionary() != nullptr) {
|
||||
ResourceMark rm; // loader_name_and_id
|
||||
stringStream tempst;
|
||||
tempst.print("System Dictionary for %s class loader", cld->loader_name_and_id());
|
||||
cld->dictionary()->print_table_statistics(st, tempst.freeze());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,7 +551,7 @@ Klass* ClassLoaderDataGraphKlassIteratorAtomic::next_klass() {
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::verify() {
|
||||
ClassLoaderDataGraphIteratorNoKeepAlive iter;
|
||||
ClassLoaderDataGraphIterator iter;
|
||||
while (ClassLoaderData* cld = iter.get_next()) {
|
||||
cld->verify();
|
||||
}
|
||||
|
||||
@@ -37,10 +37,10 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
friend class ClassLoaderDataGraphMetaspaceIterator;
|
||||
friend class ClassLoaderDataGraphKlassIteratorAtomic;
|
||||
friend class ClassLoaderDataGraphKlassIteratorStatic;
|
||||
template <bool keep_alive>
|
||||
friend class ClassLoaderDataGraphIteratorBase;
|
||||
friend class VMStructs;
|
||||
private:
|
||||
class ClassLoaderDataGraphIterator;
|
||||
|
||||
// All CLDs (except unlinked CLDs) can be reached by walking _head->_next->...
|
||||
static ClassLoaderData* volatile _head;
|
||||
|
||||
@@ -71,8 +71,12 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
static void roots_cld_do(CLDClosure* strong, CLDClosure* weak);
|
||||
static void always_strong_cld_do(CLDClosure* cl);
|
||||
// Iteration through CLDG not by GC.
|
||||
// All the do suffixed functions do not keep the CLD alive. Any CLD OopHandles
|
||||
// (modules, mirrors, resolved refs) resolved must be treated as no keepalive.
|
||||
// And requires that its CLD's holder is kept alive if they escape the
|
||||
// caller's safepoint or ClassLoaderDataGraph_lock critical section.
|
||||
// The do_keepalive suffixed functions will keep all CLDs alive.
|
||||
static void loaded_cld_do(CLDClosure* cl);
|
||||
static void loaded_cld_do_no_keepalive(CLDClosure* cl);
|
||||
// klass do
|
||||
// Walking classes through the ClassLoaderDataGraph include array classes. It also includes
|
||||
// classes that are allocated but not loaded, classes that have errors, and scratch classes
|
||||
@@ -81,9 +85,10 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
static void classes_do(KlassClosure* klass_closure);
|
||||
static void classes_do(void f(Klass* const));
|
||||
static void methods_do(void f(Method*));
|
||||
static void modules_do_keepalive(void f(ModuleEntry*));
|
||||
static void modules_do(void f(ModuleEntry*));
|
||||
static void packages_do(void f(PackageEntry*));
|
||||
static void loaded_classes_do(KlassClosure* klass_closure);
|
||||
static void loaded_classes_do_keepalive(KlassClosure* klass_closure);
|
||||
static void classes_unloading_do(void f(Klass* const));
|
||||
static bool do_unloading();
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
|
||||
|
||||
void ClassLoaderStatsVMOperation::doit() {
|
||||
ClassLoaderStatsClosure clsc (_out);
|
||||
ClassLoaderDataGraph::loaded_cld_do_no_keepalive(&clsc);
|
||||
ClassLoaderDataGraph::loaded_cld_do(&clsc);
|
||||
clsc.print();
|
||||
}
|
||||
|
||||
|
||||
@@ -788,6 +788,7 @@ int java_lang_Class::_class_loader_offset;
|
||||
int java_lang_Class::_module_offset;
|
||||
int java_lang_Class::_protection_domain_offset;
|
||||
int java_lang_Class::_component_mirror_offset;
|
||||
int java_lang_Class::_init_lock_offset;
|
||||
int java_lang_Class::_signers_offset;
|
||||
int java_lang_Class::_name_offset;
|
||||
int java_lang_Class::_source_file_offset;
|
||||
@@ -911,6 +912,12 @@ void java_lang_Class::initialize_mirror_fields(Klass* k,
|
||||
Handle protection_domain,
|
||||
Handle classData,
|
||||
TRAPS) {
|
||||
// Allocate a simple java object for a lock.
|
||||
// This needs to be a java object because during class initialization
|
||||
// it can be held across a java call.
|
||||
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
|
||||
set_init_lock(mirror(), r);
|
||||
|
||||
// Set protection domain also
|
||||
set_protection_domain(mirror(), protection_domain());
|
||||
|
||||
@@ -1132,6 +1139,10 @@ bool java_lang_Class::restore_archived_mirror(Klass *k,
|
||||
if (!k->is_array_klass()) {
|
||||
// - local static final fields with initial values were initialized at dump time
|
||||
|
||||
// create the init_lock
|
||||
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_(false));
|
||||
set_init_lock(mirror(), r);
|
||||
|
||||
if (protection_domain.not_null()) {
|
||||
set_protection_domain(mirror(), protection_domain());
|
||||
}
|
||||
@@ -1196,6 +1207,15 @@ oop java_lang_Class::component_mirror(oop java_class) {
|
||||
return java_class->obj_field(_component_mirror_offset);
|
||||
}
|
||||
|
||||
oop java_lang_Class::init_lock(oop java_class) {
|
||||
assert(_init_lock_offset != 0, "must be set");
|
||||
return java_class->obj_field(_init_lock_offset);
|
||||
}
|
||||
void java_lang_Class::set_init_lock(oop java_class, oop init_lock) {
|
||||
assert(_init_lock_offset != 0, "must be set");
|
||||
java_class->obj_field_put(_init_lock_offset, init_lock);
|
||||
}
|
||||
|
||||
objArrayOop java_lang_Class::signers(oop java_class) {
|
||||
assert(_signers_offset != 0, "must be set");
|
||||
return (objArrayOop)java_class->obj_field(_signers_offset);
|
||||
@@ -1414,7 +1434,6 @@ void java_lang_Class::compute_offsets() {
|
||||
|
||||
InstanceKlass* k = vmClasses::Class_klass();
|
||||
CLASS_FIELDS_DO(FIELD_COMPUTE_OFFSET);
|
||||
|
||||
CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -210,6 +210,7 @@ class java_lang_String : AllStatic {
|
||||
macro(java_lang_Class, protection_domain, object_signature, false) \
|
||||
macro(java_lang_Class, signers, object_signature, false) \
|
||||
macro(java_lang_Class, source_file, object_signature, false) \
|
||||
macro(java_lang_Class, init_lock, object_signature, false)
|
||||
|
||||
class java_lang_Class : AllStatic {
|
||||
friend class VMStructs;
|
||||
@@ -226,6 +227,7 @@ class java_lang_Class : AllStatic {
|
||||
static int _static_oop_field_count_offset;
|
||||
|
||||
static int _protection_domain_offset;
|
||||
static int _init_lock_offset;
|
||||
static int _signers_offset;
|
||||
static int _class_loader_offset;
|
||||
static int _module_offset;
|
||||
@@ -240,6 +242,7 @@ class java_lang_Class : AllStatic {
|
||||
static GrowableArray<Klass*>* _fixup_mirror_list;
|
||||
static GrowableArray<Klass*>* _fixup_module_field_list;
|
||||
|
||||
static void set_init_lock(oop java_class, oop init_lock);
|
||||
static void set_protection_domain(oop java_class, oop protection_domain);
|
||||
static void set_class_loader(oop java_class, oop class_loader);
|
||||
static void set_component_mirror(oop java_class, oop comp_mirror);
|
||||
@@ -292,6 +295,10 @@ class java_lang_Class : AllStatic {
|
||||
|
||||
// Support for embedded per-class oops
|
||||
static oop protection_domain(oop java_class);
|
||||
static oop init_lock(oop java_class);
|
||||
static void clear_init_lock(oop java_class) {
|
||||
set_init_lock(java_class, nullptr);
|
||||
}
|
||||
static oop component_mirror(oop java_class);
|
||||
static objArrayOop signers(oop java_class);
|
||||
static void set_signers(oop java_class, objArrayOop signers);
|
||||
|
||||
@@ -344,8 +344,23 @@ Symbol* SymbolTable::lookup_common(const char* name,
|
||||
return sym;
|
||||
}
|
||||
|
||||
// Symbols should represent entities from the constant pool that are
|
||||
// limited to <64K in length, but usage errors creep in allowing Symbols
|
||||
// to be used for arbitrary strings. For debug builds we will assert if
|
||||
// a string is too long, whereas product builds will truncate it.
|
||||
static int check_length(const char* name, int len) {
|
||||
assert(len <= Symbol::max_length(),
|
||||
"String length %d exceeds the maximum Symbol length of %d", len, Symbol::max_length());
|
||||
if (len > Symbol::max_length()) {
|
||||
warning("A string \"%.80s ... %.80s\" exceeds the maximum Symbol "
|
||||
"length of %d and has been truncated", name, (name + len - 80), Symbol::max_length());
|
||||
len = Symbol::max_length();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
Symbol* SymbolTable::new_symbol(const char* name, int len) {
|
||||
assert(len <= Symbol::max_length(), "sanity");
|
||||
len = check_length(name, len);
|
||||
unsigned int hash = hash_symbol(name, len, _alt_hash);
|
||||
Symbol* sym = lookup_common(name, len, hash);
|
||||
if (sym == nullptr) {
|
||||
@@ -485,6 +500,7 @@ void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHa
|
||||
for (int i = 0; i < names_count; i++) {
|
||||
const char *name = names[i];
|
||||
int len = lengths[i];
|
||||
assert(len <= Symbol::max_length(), "must be - these come from the constant pool");
|
||||
unsigned int hash = hashValues[i];
|
||||
assert(lookup_shared(name, len, hash) == nullptr, "must have checked already");
|
||||
Symbol* sym = do_add_if_needed(name, len, hash, is_permanent);
|
||||
@@ -494,6 +510,7 @@ void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHa
|
||||
}
|
||||
|
||||
Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, bool is_permanent) {
|
||||
assert(len <= Symbol::max_length(), "caller should have ensured this");
|
||||
SymbolTableLookup lookup(name, len, hash);
|
||||
SymbolTableGet stg;
|
||||
bool clean_hint = false;
|
||||
@@ -542,7 +559,7 @@ Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, boo
|
||||
|
||||
Symbol* SymbolTable::new_permanent_symbol(const char* name) {
|
||||
unsigned int hash = 0;
|
||||
int len = (int)strlen(name);
|
||||
int len = check_length(name, (int)strlen(name));
|
||||
Symbol* sym = SymbolTable::lookup_only(name, len, hash);
|
||||
if (sym == nullptr) {
|
||||
sym = do_add_if_needed(name, len, hash, /* is_permanent */ true);
|
||||
|
||||
@@ -177,7 +177,7 @@ class SystemDictionary : AllStatic {
|
||||
|
||||
static void classes_do(MetaspaceClosure* it);
|
||||
// Iterate over all methods in all klasses
|
||||
|
||||
// Will not keep metadata alive. See ClassLoaderDataGraph::methods_do.
|
||||
static void methods_do(void f(Method*));
|
||||
|
||||
// Garbage collection support
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "classfile/stackMapTableFormat.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/systemDictionaryShared.hpp"
|
||||
#include "classfile/verifier.hpp"
|
||||
#include "classfile/vmClasses.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
@@ -212,6 +213,11 @@ bool Verifier::verify(InstanceKlass* klass, bool should_verify_class, TRAPS) {
|
||||
exception_name == vmSymbols::java_lang_ClassFormatError())) {
|
||||
log_info(verification)("Fail over class verification to old verifier for: %s", klass->external_name());
|
||||
log_info(class, init)("Fail over class verification to old verifier for: %s", klass->external_name());
|
||||
// Exclude any classes that fail over during dynamic dumping
|
||||
if (CDSConfig::is_dumping_dynamic_archive()) {
|
||||
SystemDictionaryShared::warn_excluded(klass, "Failed over class verification while dynamic dumping");
|
||||
SystemDictionaryShared::set_excluded(klass);
|
||||
}
|
||||
message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
|
||||
exception_message = message_buffer;
|
||||
exception_name = inference_verify(
|
||||
|
||||
@@ -529,8 +529,8 @@ class methodHandle;
|
||||
/* support for sun.security.util.math.intpoly.MontgomeryIntegerPolynomialP256 */ \
|
||||
do_class(sun_security_util_math_intpoly_MontgomeryIntegerPolynomialP256, "sun/security/util/math/intpoly/MontgomeryIntegerPolynomialP256") \
|
||||
do_intrinsic(_intpoly_montgomeryMult_P256, sun_security_util_math_intpoly_MontgomeryIntegerPolynomialP256, intPolyMult_name, intPolyMult_signature, F_R) \
|
||||
do_name(intPolyMult_name, "mult") \
|
||||
do_signature(intPolyMult_signature, "([J[J[J)I") \
|
||||
do_name(intPolyMult_name, "multImpl") \
|
||||
do_signature(intPolyMult_signature, "([J[J[J)V") \
|
||||
\
|
||||
do_class(sun_security_util_math_intpoly_IntegerPolynomial, "sun/security/util/math/intpoly/IntegerPolynomial") \
|
||||
do_intrinsic(_intpoly_assign, sun_security_util_math_intpoly_IntegerPolynomial, intPolyAssign_name, intPolyAssign_signature, F_S) \
|
||||
|
||||
@@ -557,6 +557,7 @@ class SerializeClosure;
|
||||
template(bool_array_signature, "[Z") \
|
||||
template(byte_array_signature, "[B") \
|
||||
template(char_array_signature, "[C") \
|
||||
template(int_array_signature, "[I") \
|
||||
template(runnable_signature, "Ljava/lang/Runnable;") \
|
||||
template(continuation_signature, "Ljdk/internal/vm/Continuation;") \
|
||||
template(continuationscope_signature, "Ljdk/internal/vm/ContinuationScope;") \
|
||||
|
||||
@@ -227,6 +227,11 @@ void CodeCache::initialize_heaps() {
|
||||
|
||||
if (!non_nmethod.set) {
|
||||
non_nmethod.size += compiler_buffer_size;
|
||||
// Further down, just before FLAG_SET_ERGO(), all segment sizes are
|
||||
// aligned down to the next lower multiple of min_size. For large page
|
||||
// sizes, this may result in (non_nmethod.size == 0) which is not acceptable.
|
||||
// Therefore, force non_nmethod.size to at least min_size.
|
||||
non_nmethod.size = MAX2(non_nmethod.size, min_size);
|
||||
}
|
||||
|
||||
if (!profiled.set && !non_profiled.set) {
|
||||
|
||||
@@ -897,7 +897,7 @@ void Dependencies::DepStream::print_dependency(outputStream* st, Klass* witness,
|
||||
void Dependencies::DepStream::initial_asserts(size_t byte_limit) {
|
||||
assert(must_be_in_vm(), "raw oops here");
|
||||
_byte_limit = byte_limit;
|
||||
_type = (DepType)(end_marker-1); // defeat "already at end" assert
|
||||
_type = undefined_dependency; // defeat "already at end" assert
|
||||
assert((_code!=nullptr) + (_deps!=nullptr) == 1, "one or t'other");
|
||||
}
|
||||
#endif //ASSERT
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -103,6 +103,9 @@ class Dependencies: public ResourceObj {
|
||||
// type now includes N, that is, all super types of N.
|
||||
//
|
||||
enum DepType {
|
||||
// _type is initially set to -1, to prevent "already at end" assert
|
||||
undefined_dependency = -1,
|
||||
|
||||
end_marker = 0,
|
||||
|
||||
// An 'evol' dependency simply notes that the contents of the
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user