mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2026-01-06 00:21:41 +01:00
Compare commits
461 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d354141aa1 | ||
|
|
c86592d38d | ||
|
|
3660a90ad8 | ||
|
|
7f47c51ace | ||
|
|
36de19d462 | ||
|
|
ab1934848b | ||
|
|
b4f5379d50 | ||
|
|
0461d9a7d6 | ||
|
|
2a76ad975c | ||
|
|
b3fec6b5f3 | ||
|
|
11394828b3 | ||
|
|
2182c93689 | ||
|
|
613a3cc689 | ||
|
|
613d32c282 | ||
|
|
f1e8787393 | ||
|
|
47624f6fc6 | ||
|
|
2d5829afbc | ||
|
|
0064cf90ff | ||
|
|
3a7525d5c3 | ||
|
|
f4c5db92ea | ||
|
|
7452d50be5 | ||
|
|
3e39d7b34c | ||
|
|
ee6f25b507 | ||
|
|
e05cafda78 | ||
|
|
d3c3f0e7c8 | ||
|
|
576c9bccfb | ||
|
|
5411ad2a5c | ||
|
|
75ce02fe74 | ||
|
|
328b381075 | ||
|
|
d051f22284 | ||
|
|
1ca2cfafdd | ||
|
|
d3534b08b5 | ||
|
|
864a876ebf | ||
|
|
4679e9aa00 | ||
|
|
b9983c7229 | ||
|
|
a5818972c1 | ||
|
|
c4c66aba93 | ||
|
|
88b9cdae8f | ||
|
|
c9d23c3940 | ||
|
|
3934127b08 | ||
|
|
83eb20651f | ||
|
|
1183b221c2 | ||
|
|
988e1dfe6e | ||
|
|
ce0ca47641 | ||
|
|
db3402577a | ||
|
|
1ec0d02717 | ||
|
|
96bec3584c | ||
|
|
d2260146c9 | ||
|
|
c593f8bf59 | ||
|
|
4f9f1955ab | ||
|
|
2915d74a10 | ||
|
|
ddd071617e | ||
|
|
141dae8b76 | ||
|
|
667cca9d7a | ||
|
|
b9dcd4b741 | ||
|
|
d52a995f35 | ||
|
|
957703b1f9 | ||
|
|
5b5fd3694a | ||
|
|
abad0408e8 | ||
|
|
9123961aaa | ||
|
|
4a142c3b08 | ||
|
|
77fe0fd9e6 | ||
|
|
a9b31b587c | ||
|
|
e1a458ee64 | ||
|
|
40a3c35aa5 | ||
|
|
3885dc5b9a | ||
|
|
9864951dce | ||
|
|
744e089310 | ||
|
|
ec1bf23d01 | ||
|
|
3cea892bd4 | ||
|
|
bc1ba24ca5 | ||
|
|
970cd20204 | ||
|
|
37c40a11a7 | ||
|
|
723db2dc86 | ||
|
|
811b436e5d | ||
|
|
a542f7398d | ||
|
|
d96f38b80c | ||
|
|
10427c023a | ||
|
|
ca3bdfc0c7 | ||
|
|
a5208870e1 | ||
|
|
cf4ede0e54 | ||
|
|
9e98ee6726 | ||
|
|
29d462a072 | ||
|
|
43f31d7385 | ||
|
|
cee44a6255 | ||
|
|
b026d0b480 | ||
|
|
3abd772672 | ||
|
|
202c0137b8 | ||
|
|
c587211bf8 | ||
|
|
42b9ac8a07 | ||
|
|
14090ef603 | ||
|
|
d2d1592dd9 | ||
|
|
c3cdfe2a32 | ||
|
|
ba7d08b819 | ||
|
|
d7205e690f | ||
|
|
5ce718eb17 | ||
|
|
f1dfdc1a79 | ||
|
|
9c819fd3b7 | ||
|
|
1ddf826aea | ||
|
|
1f2a80b78a | ||
|
|
116503754c | ||
|
|
6f352740cb | ||
|
|
e2720987b9 | ||
|
|
54c613acd7 | ||
|
|
e67550cfec | ||
|
|
8879c78d62 | ||
|
|
f9795d0d09 | ||
|
|
d1077d6f14 | ||
|
|
21d8a4725f | ||
|
|
d4b761242d | ||
|
|
bf1a14e367 | ||
|
|
5224e979a1 | ||
|
|
9bfa082970 | ||
|
|
3f446c5156 | ||
|
|
0baa9ecd76 | ||
|
|
4a16d111b1 | ||
|
|
a644670cc6 | ||
|
|
e6f23a90d4 | ||
|
|
fd332da1c8 | ||
|
|
6d3cb459dc | ||
|
|
cb383c05b2 | ||
|
|
4bfe226870 | ||
|
|
08f79148c6 | ||
|
|
728b858c78 | ||
|
|
eb5916729d | ||
|
|
1b150117fd | ||
|
|
5ba9705d60 | ||
|
|
8d9a4b43f4 | ||
|
|
69c0ae23a3 | ||
|
|
c1aeac79ba | ||
|
|
d888b26783 | ||
|
|
bea2d48696 | ||
|
|
9f767aa44b | ||
|
|
bd22d2381f | ||
|
|
c2efd77412 | ||
|
|
99de9bb83f | ||
|
|
704c6ea16c | ||
|
|
7c0a8288b2 | ||
|
|
ff5c5b6541 | ||
|
|
fc29a2e152 | ||
|
|
729f4c5d14 | ||
|
|
4eab39d941 | ||
|
|
ffadd63575 | ||
|
|
ecd25e7d6f | ||
|
|
a876beb63d | ||
|
|
4cf195f00c | ||
|
|
af2f4bfa83 | ||
|
|
a1a62d9964 | ||
|
|
77b2394c46 | ||
|
|
d3ebb4a155 | ||
|
|
66d90d5d9f | ||
|
|
4dfa3799a6 | ||
|
|
158293d251 | ||
|
|
a045258ae2 | ||
|
|
21215753c0 | ||
|
|
200b5a27d4 | ||
|
|
52814994ef | ||
|
|
8065233e8b | ||
|
|
b1228de623 | ||
|
|
5a97411f85 | ||
|
|
91442878b7 | ||
|
|
40106422bd | ||
|
|
fe52917054 | ||
|
|
71c99a0e59 | ||
|
|
2c23391de7 | ||
|
|
deadb9c8d7 | ||
|
|
a03767cf88 | ||
|
|
848ecc1621 | ||
|
|
b07da3ae15 | ||
|
|
6f1d8962df | ||
|
|
8f4ebd8921 | ||
|
|
cd25d1a2bf | ||
|
|
744f206fef | ||
|
|
8099261050 | ||
|
|
138437f2cf | ||
|
|
4812cabaa4 | ||
|
|
bd02cfd96f | ||
|
|
bd3bc2c618 | ||
|
|
292aad2c49 | ||
|
|
387504c9e4 | ||
|
|
d9ce525a1c | ||
|
|
c46a54e018 | ||
|
|
8f5f44070a | ||
|
|
684b91efbb | ||
|
|
1740950036 | ||
|
|
cc8f8da293 | ||
|
|
599560a832 | ||
|
|
9cf334fb64 | ||
|
|
defc7e0f8d | ||
|
|
3c70f2c1e9 | ||
|
|
15acf4b8d7 | ||
|
|
1a098356dd | ||
|
|
47bb1a1cef | ||
|
|
80bd22d093 | ||
|
|
c0e154c876 | ||
|
|
24bc5bd104 | ||
|
|
e25a49a993 | ||
|
|
ce8ebebc77 | ||
|
|
ab135683a6 | ||
|
|
278de7acd2 | ||
|
|
6fc3514231 | ||
|
|
31ef400f31 | ||
|
|
4e77b3c378 | ||
|
|
8dd809642e | ||
|
|
9843c97695 | ||
|
|
7c80cb26df | ||
|
|
adca97b659 | ||
|
|
195c9b2c48 | ||
|
|
072d64c6a9 | ||
|
|
83b6a1278f | ||
|
|
cceb0d8a23 | ||
|
|
2f4d601a56 | ||
|
|
0ba48ef4ab | ||
|
|
5145e5a40a | ||
|
|
c566dfccf8 | ||
|
|
c9985720b9 | ||
|
|
d6679031e0 | ||
|
|
61cc4a011e | ||
|
|
39e2b7a6d3 | ||
|
|
d0ea2a5111 | ||
|
|
6aa837eee6 | ||
|
|
5ca1beb30e | ||
|
|
2bf1863e24 | ||
|
|
15588e08ed | ||
|
|
e649c56324 | ||
|
|
5f4be8cea9 | ||
|
|
a949824e98 | ||
|
|
7e39e664cf | ||
|
|
75b37e6d7e | ||
|
|
34653c1e73 | ||
|
|
d8cd60588a | ||
|
|
8f79d88960 | ||
|
|
b2b8db6533 | ||
|
|
5bd10521eb | ||
|
|
c64bd3d671 | ||
|
|
6ee6171e81 | ||
|
|
7ca0ae9415 | ||
|
|
5521560abd | ||
|
|
e4329a823b | ||
|
|
504b0bdaaa | ||
|
|
7b3917265d | ||
|
|
aed1e810e6 | ||
|
|
741ae06c55 | ||
|
|
8c1bb2b280 | ||
|
|
2d38495b61 | ||
|
|
0d091681c2 | ||
|
|
1a7fd5d419 | ||
|
|
eb7d972d8a | ||
|
|
7028fb9d58 | ||
|
|
36993aea9a | ||
|
|
668d4b077f | ||
|
|
a36eaf03af | ||
|
|
a27fc7efd4 | ||
|
|
37eb98604f | ||
|
|
37aed6f46d | ||
|
|
1e930db3c7 | ||
|
|
0275efac88 | ||
|
|
77d40ce166 | ||
|
|
4ea1b99c1a | ||
|
|
01ea1eff66 | ||
|
|
1d54e73f6a | ||
|
|
56aa1e8dc8 | ||
|
|
f7d6d7a04f | ||
|
|
e942f368c3 | ||
|
|
7cb2e6d65b | ||
|
|
9622de2aa8 | ||
|
|
72c4dcbfee | ||
|
|
32a60cf11d | ||
|
|
b12c471a99 | ||
|
|
605c976729 | ||
|
|
6273ab97dc | ||
|
|
7d31146f4d | ||
|
|
45b7aedabf | ||
|
|
266636deab | ||
|
|
e490cf9c65 | ||
|
|
126f2ace5d | ||
|
|
4d9042043e | ||
|
|
1082c0e767 | ||
|
|
ec310fe809 | ||
|
|
ff0b397e13 | ||
|
|
c88b387881 | ||
|
|
993951b85e | ||
|
|
17535c34bc | ||
|
|
61ce739ac8 | ||
|
|
77fa44fd4f | ||
|
|
0983b54866 | ||
|
|
64ee3c9990 | ||
|
|
32ac72c3d3 | ||
|
|
9728e21db1 | ||
|
|
a8473b7079 | ||
|
|
16fd43c5eb | ||
|
|
c1f698d38b | ||
|
|
935543146b | ||
|
|
32ccf018eb | ||
|
|
4c79e7d59c | ||
|
|
7633a76607 | ||
|
|
00ef9f9c32 | ||
|
|
77dc89115e | ||
|
|
d95b548c78 | ||
|
|
424de295a6 | ||
|
|
6d6c9008d5 | ||
|
|
eca6ea43d0 | ||
|
|
2edf9c3f1e | ||
|
|
839cb19ec2 | ||
|
|
387896fb34 | ||
|
|
8d2ad2b1ae | ||
|
|
b92de54a81 | ||
|
|
2a80160960 | ||
|
|
3f6d01687c | ||
|
|
2d46b29728 | ||
|
|
8f8c45b54a | ||
|
|
8a9c4d5266 | ||
|
|
bcafec54a5 | ||
|
|
731fb4eea2 | ||
|
|
79761519f6 | ||
|
|
ca96fd3b07 | ||
|
|
a9b41da9df | ||
|
|
0fd807118c | ||
|
|
1161e3da14 | ||
|
|
e55c482ce1 | ||
|
|
84b7cc15c2 | ||
|
|
3aa4cba175 | ||
|
|
54861df3d9 | ||
|
|
f40ea5109e | ||
|
|
fec1d49783 | ||
|
|
2b8276aa52 | ||
|
|
33591a30d2 | ||
|
|
fb4098ff1a | ||
|
|
c2abf120bc | ||
|
|
ad7a8e86e0 | ||
|
|
fcff222f92 | ||
|
|
ef41aa02b8 | ||
|
|
ad6dce376d | ||
|
|
e882718a60 | ||
|
|
d313915974 | ||
|
|
053f45695f | ||
|
|
5b311f20df | ||
|
|
8e0686b065 | ||
|
|
5e8d893c48 | ||
|
|
f61499c73f | ||
|
|
3ff5a781db | ||
|
|
508fa71753 | ||
|
|
1f06325142 | ||
|
|
a07a4a3a59 | ||
|
|
7ff19383fd | ||
|
|
a57ae7e7d4 | ||
|
|
6ddbfaae49 | ||
|
|
0cf1a558ba | ||
|
|
bcc986b9d1 | ||
|
|
460ebcd9cb | ||
|
|
dc4bc4f084 | ||
|
|
a4e9168bab | ||
|
|
6c6beba256 | ||
|
|
b62e774e6a | ||
|
|
a64794b1ed | ||
|
|
b3cc0c8431 | ||
|
|
691db5df73 | ||
|
|
ec9ba5dae9 | ||
|
|
7162624d70 | ||
|
|
f0d66d1fd3 | ||
|
|
991ce84e09 | ||
|
|
8a30c2a9b2 | ||
|
|
a1c9587c27 | ||
|
|
a8eacb31ab | ||
|
|
4c5b66dcea | ||
|
|
42be23877c | ||
|
|
a250ae4d1b | ||
|
|
1ed9c76ec8 | ||
|
|
3630af26e6 | ||
|
|
c6c69b579c | ||
|
|
3105538de5 | ||
|
|
36314a90c1 | ||
|
|
ddacf92713 | ||
|
|
4195246fba | ||
|
|
0a3a925ad8 | ||
|
|
b0d6c8472f | ||
|
|
a8549b6367 | ||
|
|
9718f490fb | ||
|
|
0d4de8a71f | ||
|
|
d4c904d819 | ||
|
|
48f1a925e5 | ||
|
|
0b0f8b55a6 | ||
|
|
8c0d026d0f | ||
|
|
f7deaf4bef | ||
|
|
8ff10a0d35 | ||
|
|
1809b8cdd6 | ||
|
|
cfabcbf858 | ||
|
|
b859da9c54 | ||
|
|
b438cffdb9 | ||
|
|
ae796a4e10 | ||
|
|
89987dbf87 | ||
|
|
0e501f66df | ||
|
|
c47a0ce3f0 | ||
|
|
353d139682 | ||
|
|
3bcfac18c3 | ||
|
|
b6a97c0780 | ||
|
|
287b243221 | ||
|
|
26c21f50a3 | ||
|
|
6e1aacdfba | ||
|
|
d2e2c4cef1 | ||
|
|
e25121d1d9 | ||
|
|
5c8366eea4 | ||
|
|
ad81abd2db | ||
|
|
d7d1d42b67 | ||
|
|
f985006142 | ||
|
|
a564d436c7 | ||
|
|
878d27dba1 | ||
|
|
2637e8ddc4 | ||
|
|
8093563bce | ||
|
|
516cfb135f | ||
|
|
59847926b6 | ||
|
|
eeb63cd0fa | ||
|
|
69489427e9 | ||
|
|
795e5dcc85 | ||
|
|
207819a05e | ||
|
|
8fcf70e931 | ||
|
|
93f662f4fc | ||
|
|
b8fa6c23f5 | ||
|
|
fb055e7e53 | ||
|
|
009f5e1fa1 | ||
|
|
47569a256c | ||
|
|
5a6aa569aa | ||
|
|
014c95a54d | ||
|
|
fa0697a637 | ||
|
|
49376e4452 | ||
|
|
a185be0346 | ||
|
|
179792beb4 | ||
|
|
bd918f49d2 | ||
|
|
c45308afac | ||
|
|
bd7bb67d8f | ||
|
|
0259da9283 | ||
|
|
355811a996 | ||
|
|
ecb5e8a03f | ||
|
|
f2c221def1 | ||
|
|
09dad0e96b | ||
|
|
73a47f0c4a | ||
|
|
cfcbfc6cae | ||
|
|
ca5eee2fe3 | ||
|
|
060db1b2a2 | ||
|
|
3481a48571 | ||
|
|
29348b3cf6 | ||
|
|
3f19df685c | ||
|
|
fc98998627 | ||
|
|
065203d44a | ||
|
|
0c55887bfb | ||
|
|
1230aed61d | ||
|
|
d0c1444d92 | ||
|
|
bc5a39bb54 | ||
|
|
3481ecb255 | ||
|
|
798125152b | ||
|
|
77fac0f4c6 | ||
|
|
2d154fcd0d | ||
|
|
42924ed4e5 | ||
|
|
384d2ea6d1 | ||
|
|
84390dd063 | ||
|
|
52073b27a3 | ||
|
|
83c0e45160 | ||
|
|
d3a79b5861 | ||
|
|
750da00129 | ||
|
|
b8cec480f8 | ||
|
|
5350fd6173 |
2
.github/workflows/build-macos.yml
vendored
2
.github/workflows/build-macos.yml
vendored
@@ -55,7 +55,7 @@ on:
|
||||
jobs:
|
||||
build-macos:
|
||||
name: build
|
||||
runs-on: macos-11
|
||||
runs-on: macos-13
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
12
.github/workflows/main.yml
vendored
12
.github/workflows/main.yml
vendored
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -146,8 +146,8 @@ jobs:
|
||||
apt-architecture: 'i386'
|
||||
# Some multilib libraries do not have proper inter-dependencies, so we have to
|
||||
# install their dependencies manually.
|
||||
apt-extra-packages: 'libfreetype-dev:i386 libtiff-dev:i386 libcupsimage2-dev:i386 libc6-i386 libgcc-s1:i386 libstdc++6:i386'
|
||||
extra-conf-options: '--with-target-bits=32'
|
||||
apt-extra-packages: 'libfreetype-dev:i386 libtiff-dev:i386 libcupsimage2-dev:i386 libc6-i386 libgcc-s1:i386 libstdc++6:i386 libffi-dev:i386'
|
||||
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'
|
||||
@@ -227,7 +227,7 @@ jobs:
|
||||
uses: ./.github/workflows/build-macos.yml
|
||||
with:
|
||||
platform: macos-x64
|
||||
xcode-toolset-version: '12.5.1'
|
||||
xcode-toolset-version: '14.3.1'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.macos-x64 == 'true'
|
||||
@@ -238,7 +238,7 @@ jobs:
|
||||
uses: ./.github/workflows/build-macos.yml
|
||||
with:
|
||||
platform: macos-aarch64
|
||||
xcode-toolset-version: '12.5.1'
|
||||
xcode-toolset-version: '14.3.1'
|
||||
extra-conf-options: '--openjdk-target=aarch64-apple-darwin'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
@@ -318,7 +318,7 @@ jobs:
|
||||
with:
|
||||
platform: macos-x64
|
||||
bootjdk-platform: macos-x64
|
||||
runs-on: macos-11
|
||||
runs-on: macos-13
|
||||
|
||||
test-windows-x64:
|
||||
name: windows-x64
|
||||
|
||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -132,7 +132,7 @@ jobs:
|
||||
run: |
|
||||
# On macOS we need to install some dependencies for testing
|
||||
brew install make
|
||||
sudo xcode-select --switch /Applications/Xcode_11.7.app/Contents/Developer
|
||||
sudo xcode-select --switch /Applications/Xcode_14.3.1.app/Contents/Developer
|
||||
# This will make GNU make available as 'make' and not only as 'gmake'
|
||||
echo '/usr/local/opt/make/libexec/gnubin' >> $GITHUB_PATH
|
||||
if: runner.os == 'macOS'
|
||||
|
||||
@@ -367,7 +367,7 @@ to date at the time of writing.</p>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>macOS</td>
|
||||
<td>Mac OS X 10.13 (High Sierra)</td>
|
||||
<td>macOS 13 (Ventura)</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Windows</td>
|
||||
@@ -464,9 +464,8 @@ this makes it difficult for a project such as the JDK to keep pace with
|
||||
a continuously updated machine running macOS. See the section on <a
|
||||
href="#apple-xcode">Apple Xcode</a> on some strategies to deal with
|
||||
this.</p>
|
||||
<p>It is recommended that you use at least Mac OS X 10.13 (High Sierra).
|
||||
At the time of writing, the JDK has been successfully compiled on macOS
|
||||
10.12 (Sierra).</p>
|
||||
<p>It is recommended that you use at least macOS 13 (Ventura) and Xcode
|
||||
14, but earlier versions may also work.</p>
|
||||
<p>The standard macOS environment contains the basic tooling needed to
|
||||
build, but for external libraries a package manager is recommended. The
|
||||
JDK uses <a href="https://brew.sh/">homebrew</a> in the examples, but
|
||||
@@ -545,7 +544,7 @@ to compile successfully without issues.</p>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>macOS</td>
|
||||
<td>Apple Xcode 10.1 (using clang 10.0.0)</td>
|
||||
<td>Apple Xcode 14.3.1 (using clang 14.0.3)</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>Windows</td>
|
||||
@@ -820,11 +819,11 @@ about the problem.</p>
|
||||
<p>Some command line examples:</p>
|
||||
<ul>
|
||||
<li><p>Create a 32-bit build for Windows with FreeType2 in
|
||||
<code>C:\freetype-i586</code>:
|
||||
<code>bash configure --with-freetype=/cygdrive/c/freetype-i586 --with-target-bits=32</code></p></li>
|
||||
<code>C:\freetype-i586</code>:</p>
|
||||
<pre><code>bash configure --with-freetype=/cygdrive/c/freetype-i586 --with-target-bits=32</code></pre></li>
|
||||
<li><p>Create a debug build with the <code>server</code> JVM and DTrace
|
||||
enabled:
|
||||
<code>bash configure --enable-debug --with-jvm-variants=server --enable-dtrace</code></p></li>
|
||||
enabled:</p>
|
||||
<pre><code>bash configure --enable-debug --with-jvm-variants=server --enable-dtrace</code></pre></li>
|
||||
</ul>
|
||||
<h3 id="common-configure-arguments">Common Configure Arguments</h3>
|
||||
<p>Here follows some of the most common and important
|
||||
@@ -1332,14 +1331,12 @@ Package Search</a> and search for the <code>libasound2</code> and
|
||||
<code>libasound2-dev</code> packages for your <em>target</em> system.
|
||||
Download them to /tmp.</p></li>
|
||||
<li><p>Install the libraries into the cross-compilation toolchain. For
|
||||
instance:</p></li>
|
||||
</ul>
|
||||
instance:</p>
|
||||
<pre><code>cd /tools/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux/arm-linux-gnueabihf/libc
|
||||
dpkg-deb -x /tmp/libasound2_1.0.25-4_armhf.deb .
|
||||
dpkg-deb -x /tmp/libasound2-dev_1.0.25-4_armhf.deb .</code></pre>
|
||||
<ul>
|
||||
<li>If alsa is not properly detected by <code>configure</code>, you can
|
||||
point it out by <code>--with-alsa</code>.</li>
|
||||
dpkg-deb -x /tmp/libasound2-dev_1.0.25-4_armhf.deb .</code></pre></li>
|
||||
<li><p>If alsa is not properly detected by <code>configure</code>, you
|
||||
can point it out by <code>--with-alsa</code>.</p></li>
|
||||
</ul>
|
||||
<h4 id="x11-1">X11</h4>
|
||||
<p>You will need X11 libraries suitable for your <em>target</em> system.
|
||||
@@ -1373,21 +1370,18 @@ Package Search</a>, search for the following packages for your
|
||||
</ul></li>
|
||||
<li><p>Install the libraries into the cross-compilation toolchain. For
|
||||
instance:</p>
|
||||
<pre><code> cd /tools/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux/arm-linux-gnueabihf/libc/usr
|
||||
mkdir X11R6
|
||||
cd X11R6
|
||||
for deb in /tmp/target-x11/*.deb ; do dpkg-deb -x $deb . ; done
|
||||
mv usr/* .
|
||||
cd lib
|
||||
cp arm-linux-gnueabihf/* .
|
||||
```
|
||||
|
||||
You can ignore the following messages. These libraries are not needed to
|
||||
successfully complete a full JDK build.</code></pre>
|
||||
<p>cp: cannot stat
|
||||
<code>arm-linux-gnueabihf/libICE.so': No such file or directory cp: cannot stat</code>arm-linux-gnueabihf/libSM.so':
|
||||
No such file or directory cp: cannot stat
|
||||
`arm-linux-gnueabihf/libXt.so': No such file or directory ```</p></li>
|
||||
<pre><code>cd /tools/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux/arm-linux-gnueabihf/libc/usr
|
||||
mkdir X11R6
|
||||
cd X11R6
|
||||
for deb in /tmp/target-x11/*.deb ; do dpkg-deb -x $deb . ; done
|
||||
mv usr/* .
|
||||
cd lib
|
||||
cp arm-linux-gnueabihf/* .</code></pre>
|
||||
<p>You can ignore the following messages. These libraries are not needed
|
||||
to successfully complete a full JDK build.</p>
|
||||
<pre><code>cp: cannot stat `arm-linux-gnueabihf/libICE.so': No such file or directory
|
||||
cp: cannot stat `arm-linux-gnueabihf/libSM.so': No such file or directory
|
||||
cp: cannot stat `arm-linux-gnueabihf/libXt.so': No such file or directory</code></pre></li>
|
||||
<li><p>If the X11 libraries are not properly detected by
|
||||
<code>configure</code>, you can point them out by
|
||||
<code>--with-x</code>.</p></li>
|
||||
@@ -1405,17 +1399,41 @@ native compilation speed.</p>
|
||||
<p>For example, cross-compiling to AArch64 from x86_64 could be done
|
||||
like this:</p>
|
||||
<ul>
|
||||
<li><p>Install cross-compiler on the <em>build</em> system:
|
||||
<code>apt install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu</code></p></li>
|
||||
<li><p>Install cross-compiler on the <em>build</em> system:</p>
|
||||
<pre><code>apt install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu</code></pre></li>
|
||||
<li><p>Create chroot on the <em>build</em> system, configuring it for
|
||||
<em>target</em> system:
|
||||
<code>sudo debootstrap \ --arch=arm64 \ --verbose \ --include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev,libffi-dev \ --resolve-deps \ buster \ ~/sysroot-arm64 \ http://httpredir.debian.org/debian/ # If the target architecture is `riscv64`, # the path should be `debian-ports` instead of `debian`.</code></p></li>
|
||||
<em>target</em> system:</p>
|
||||
<pre><code>sudo debootstrap \
|
||||
--arch=arm64 \
|
||||
--verbose \
|
||||
--include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev,libffi-dev \
|
||||
--resolve-deps \
|
||||
buster \
|
||||
~/sysroot-arm64 \
|
||||
http://httpredir.debian.org/debian/
|
||||
# If the target architecture is `riscv64`,
|
||||
# the path should be `debian-ports` instead of `debian`.</code></pre></li>
|
||||
<li><p>To create a Ubuntu-based chroot:</p>
|
||||
<pre><code>sudo debootstrap \
|
||||
--arch=arm64 \
|
||||
--verbose \
|
||||
--components=main,universe \
|
||||
--include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev,libffi-dev \
|
||||
--resolve-deps \
|
||||
jammy \
|
||||
~/sysroot-arm64 \
|
||||
http://ports.ubuntu.com/ubuntu-ports/
|
||||
# symlinks is in the universe repository</code></pre></li>
|
||||
<li><p>Make sure the symlinks inside the newly created chroot point to
|
||||
proper locations:
|
||||
<code>sudo chroot ~/sysroot-arm64 symlinks -cr .</code></p></li>
|
||||
proper locations:</p>
|
||||
<pre><code>sudo chroot ~/sysroot-arm64 symlinks -cr .</code></pre></li>
|
||||
<li><p>Configure and build with newly created chroot as
|
||||
sysroot/toolchain-path:
|
||||
<code>sh ./configure \ --openjdk-target=aarch64-linux-gnu \ --with-sysroot=~/sysroot-arm64 make images ls build/linux-aarch64-server-release/</code></p></li>
|
||||
sysroot/toolchain-path:</p>
|
||||
<pre><code>sh ./configure \
|
||||
--openjdk-target=aarch64-linux-gnu \
|
||||
--with-sysroot=~/sysroot-arm64
|
||||
make images
|
||||
ls build/linux-aarch64-server-release/</code></pre></li>
|
||||
</ul>
|
||||
<p>The build does not create new files in that chroot, so it can be
|
||||
reused for multiple builds without additional cleanup.</p>
|
||||
@@ -1567,12 +1585,27 @@ libraries</a> required by OpenJDK complicate the building process. The
|
||||
placeholder <code><toolchain-installed-path></code> shown below is
|
||||
the path where you want to install the toolchain.</p>
|
||||
<ul>
|
||||
<li><p>Install the RISC-V GNU compiler toolchain:
|
||||
<code>git clone --recursive https://github.com/riscv-collab/riscv-gnu-toolchain cd riscv-gnu-toolchain ./configure --prefix=<toolchain-installed-path> make linux export PATH=<toolchain-installed-path>/bin:$PATH</code></p></li>
|
||||
<li><p>Cross-compile all the required libraries:
|
||||
<code># An example for libffi git clone https://github.com/libffi/libffi cd libffi ./configure --host=riscv64-unknown-linux-gnu --prefix=<toolchain-installed-path>/sysroot/usr make make install</code></p></li>
|
||||
<li><p>Configure and build OpenJDK:
|
||||
<code>bash configure \ --with-boot-jdk=$BOOT_JDK \ --openjdk-target=riscv64-linux-gnu \ --with-sysroot=<toolchain-installed-path>/sysroot \ --with-toolchain-path=<toolchain-installed-path>/bin \ --with-extra-path=<toolchain-installed-path>/bin make images</code></p></li>
|
||||
<li><p>Install the RISC-V GNU compiler toolchain:</p>
|
||||
<pre><code>git clone --recursive https://github.com/riscv-collab/riscv-gnu-toolchain
|
||||
cd riscv-gnu-toolchain
|
||||
./configure --prefix=<toolchain-installed-path>
|
||||
make linux
|
||||
export PATH=<toolchain-installed-path>/bin:$PATH</code></pre></li>
|
||||
<li><p>Cross-compile all the required libraries:</p>
|
||||
<pre><code># An example for libffi
|
||||
git clone https://github.com/libffi/libffi
|
||||
cd libffi
|
||||
./configure --host=riscv64-unknown-linux-gnu --prefix=<toolchain-installed-path>/sysroot/usr
|
||||
make
|
||||
make install</code></pre></li>
|
||||
<li><p>Configure and build OpenJDK:</p>
|
||||
<pre><code>bash configure \
|
||||
--with-boot-jdk=$BOOT_JDK \
|
||||
--openjdk-target=riscv64-linux-gnu \
|
||||
--with-sysroot=<toolchain-installed-path>/sysroot \
|
||||
--with-toolchain-path=<toolchain-installed-path>/bin \
|
||||
--with-extra-path=<toolchain-installed-path>/bin
|
||||
make images</code></pre></li>
|
||||
</ul>
|
||||
<h3 id="building-for-musl">Building for musl</h3>
|
||||
<p>Just like it's possible to cross-compile for a different CPU, it's
|
||||
|
||||
@@ -167,7 +167,7 @@ time of writing.
|
||||
| Operating system | Vendor/version used |
|
||||
| ----------------- | ---------------------------------- |
|
||||
| Linux | Oracle Enterprise Linux 6.4 / 7.6 |
|
||||
| macOS | Mac OS X 10.13 (High Sierra) |
|
||||
| macOS | macOS 13 (Ventura) |
|
||||
| Windows | Windows Server 2012 R2 |
|
||||
|
||||
The double version numbers for Linux are due to the hybrid model
|
||||
@@ -270,8 +270,8 @@ difficult for a project such as the JDK to keep pace with a continuously updated
|
||||
machine running macOS. See the section on [Apple Xcode](#apple-xcode) on some
|
||||
strategies to deal with this.
|
||||
|
||||
It is recommended that you use at least Mac OS X 10.13 (High Sierra). At the time
|
||||
of writing, the JDK has been successfully compiled on macOS 10.12 (Sierra).
|
||||
It is recommended that you use at least macOS 13 (Ventura) and Xcode
|
||||
14, but earlier versions may also work.
|
||||
|
||||
The standard macOS environment contains the basic tooling needed to build, but
|
||||
for external libraries a package manager is recommended. The JDK uses
|
||||
@@ -337,7 +337,7 @@ issues.
|
||||
| Operating system | Toolchain version |
|
||||
| ------------------ | ------------------------------------------ |
|
||||
| Linux | gcc 11.2.0 |
|
||||
| macOS | Apple Xcode 10.1 (using clang 10.0.0) |
|
||||
| macOS | Apple Xcode 14.3.1 (using clang 14.0.3) |
|
||||
| Windows | Microsoft Visual Studio 2022 update 17.1.0 |
|
||||
|
||||
All compilers are expected to be able to compile to the C99 language standard,
|
||||
@@ -626,11 +626,13 @@ automatically, it will exit and inform you about the problem.
|
||||
Some command line examples:
|
||||
|
||||
* Create a 32-bit build for Windows with FreeType2 in `C:\freetype-i586`:
|
||||
|
||||
```
|
||||
bash configure --with-freetype=/cygdrive/c/freetype-i586 --with-target-bits=32
|
||||
```
|
||||
|
||||
* Create a debug build with the `server` JVM and DTrace enabled:
|
||||
|
||||
```
|
||||
bash configure --enable-debug --with-jvm-variants=server --enable-dtrace
|
||||
```
|
||||
@@ -1100,11 +1102,12 @@ Note that alsa is needed even if you only want to build a headless JDK.
|
||||
system. Download them to /tmp.
|
||||
|
||||
* Install the libraries into the cross-compilation toolchain. For instance:
|
||||
```
|
||||
cd /tools/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux/arm-linux-gnueabihf/libc
|
||||
dpkg-deb -x /tmp/libasound2_1.0.25-4_armhf.deb .
|
||||
dpkg-deb -x /tmp/libasound2-dev_1.0.25-4_armhf.deb .
|
||||
```
|
||||
|
||||
```
|
||||
cd /tools/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux/arm-linux-gnueabihf/libc
|
||||
dpkg-deb -x /tmp/libasound2_1.0.25-4_armhf.deb .
|
||||
dpkg-deb -x /tmp/libasound2-dev_1.0.25-4_armhf.deb .
|
||||
```
|
||||
|
||||
* If alsa is not properly detected by `configure`, you can point it out by
|
||||
`--with-alsa`.
|
||||
@@ -1140,6 +1143,7 @@ Note that X11 is needed even if you only want to build a headless JDK.
|
||||
* libxext-dev
|
||||
|
||||
* Install the libraries into the cross-compilation toolchain. For instance:
|
||||
|
||||
```
|
||||
cd /tools/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux/arm-linux-gnueabihf/libc/usr
|
||||
mkdir X11R6
|
||||
@@ -1173,11 +1177,13 @@ for foreign architectures with native compilation speed.
|
||||
For example, cross-compiling to AArch64 from x86_64 could be done like this:
|
||||
|
||||
* Install cross-compiler on the *build* system:
|
||||
|
||||
```
|
||||
apt install g++-aarch64-linux-gnu gcc-aarch64-linux-gnu
|
||||
```
|
||||
|
||||
* Create chroot on the *build* system, configuring it for *target* system:
|
||||
|
||||
```
|
||||
sudo debootstrap \
|
||||
--arch=arm64 \
|
||||
@@ -1191,12 +1197,29 @@ For example, cross-compiling to AArch64 from x86_64 could be done like this:
|
||||
# the path should be `debian-ports` instead of `debian`.
|
||||
```
|
||||
|
||||
* To create a Ubuntu-based chroot:
|
||||
|
||||
```
|
||||
sudo debootstrap \
|
||||
--arch=arm64 \
|
||||
--verbose \
|
||||
--components=main,universe \
|
||||
--include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev,libffi-dev \
|
||||
--resolve-deps \
|
||||
jammy \
|
||||
~/sysroot-arm64 \
|
||||
http://ports.ubuntu.com/ubuntu-ports/
|
||||
# symlinks is in the universe repository
|
||||
```
|
||||
|
||||
* Make sure the symlinks inside the newly created chroot point to proper locations:
|
||||
|
||||
```
|
||||
sudo chroot ~/sysroot-arm64 symlinks -cr .
|
||||
```
|
||||
|
||||
* Configure and build with newly created chroot as sysroot/toolchain-path:
|
||||
|
||||
```
|
||||
sh ./configure \
|
||||
--openjdk-target=aarch64-linux-gnu \
|
||||
@@ -1255,6 +1278,7 @@ complicate the building process. The placeholder `<toolchain-installed-path>`
|
||||
shown below is the path where you want to install the toolchain.
|
||||
|
||||
* Install the RISC-V GNU compiler toolchain:
|
||||
|
||||
```
|
||||
git clone --recursive https://github.com/riscv-collab/riscv-gnu-toolchain
|
||||
cd riscv-gnu-toolchain
|
||||
@@ -1264,6 +1288,7 @@ shown below is the path where you want to install the toolchain.
|
||||
```
|
||||
|
||||
* Cross-compile all the required libraries:
|
||||
|
||||
```
|
||||
# An example for libffi
|
||||
git clone https://github.com/libffi/libffi
|
||||
@@ -1274,6 +1299,7 @@ shown below is the path where you want to install the toolchain.
|
||||
```
|
||||
|
||||
* Configure and build OpenJDK:
|
||||
|
||||
```
|
||||
bash configure \
|
||||
--with-boot-jdk=$BOOT_JDK \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -81,13 +81,11 @@ endif
|
||||
ifneq ($(CMDS_DIR), )
|
||||
DEPS += $(call FindFiles, $(CMDS_DIR))
|
||||
ifeq ($(call isTargetOs, windows)+$(SHIP_DEBUG_SYMBOLS), true+public)
|
||||
# For public debug symbols on Windows, we have to use stripped pdbs, rename them
|
||||
# and filter out a few launcher pdbs where there's a lib that goes by the same name
|
||||
# For public debug symbols on Windows, we have to use stripped pdbs and rename them
|
||||
rename_stripped = $(patsubst %.stripped.pdb,%.pdb,$1)
|
||||
CMDS_DIR_FILTERED := $(subst modules_cmds,modules_cmds_filtered, $(CMDS_DIR))
|
||||
FILES_CMDS := $(filter-out %.pdb, $(call FindFiles, $(CMDS_DIR))) \
|
||||
$(filter-out %jimage.stripped.pdb %jpackage.stripped.pdb %java.stripped.pdb, \
|
||||
$(filter %.stripped.pdb, $(call FindFiles, $(CMDS_DIR))))
|
||||
$(filter %.stripped.pdb, $(call FindFiles, $(CMDS_DIR)))
|
||||
$(eval $(call SetupCopyFiles, COPY_FILTERED_CMDS, \
|
||||
SRC := $(CMDS_DIR), \
|
||||
DEST := $(CMDS_DIR_FILTERED), \
|
||||
@@ -96,18 +94,6 @@ ifneq ($(CMDS_DIR), )
|
||||
))
|
||||
DEPS += $(COPY_FILTERED_CMDS)
|
||||
JMOD_FLAGS += --cmds $(CMDS_DIR_FILTERED)
|
||||
else ifeq ($(call isTargetOs, windows)+$(SHIP_DEBUG_SYMBOLS), true+full)
|
||||
# For full debug symbols on Windows, we have to filter out a few launcher pdbs
|
||||
# where there's a lib that goes by the same name
|
||||
CMDS_DIR_FILTERED := $(subst modules_cmds,modules_cmds_filtered, $(CMDS_DIR))
|
||||
$(eval $(call SetupCopyFiles, COPY_FILTERED_CMDS, \
|
||||
SRC := $(CMDS_DIR), \
|
||||
DEST := $(CMDS_DIR_FILTERED), \
|
||||
FILES := $(filter-out %jimage.pdb %jpackage.pdb %java.pdb, \
|
||||
$(call FindFiles, $(CMDS_DIR))), \
|
||||
))
|
||||
DEPS += $(COPY_FILTERED_CMDS)
|
||||
JMOD_FLAGS += --cmds $(CMDS_DIR_FILTERED)
|
||||
else
|
||||
JMOD_FLAGS += --cmds $(CMDS_DIR)
|
||||
endif
|
||||
|
||||
@@ -274,9 +274,6 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
FILTERED_PDBS := %jimage.stripped.pdb %jpackage.stripped.pdb %java.stripped.pdb \
|
||||
%jimage.pdb %jpackage.pdb %java.pdb %jimage.map %jpackage.map %java.map
|
||||
|
||||
# Param 1 - either JDK or JRE
|
||||
SetupCopyDebuginfo = \
|
||||
$(foreach m, $(ALL_$1_MODULES), \
|
||||
@@ -290,8 +287,8 @@ SetupCopyDebuginfo = \
|
||||
$(eval $(call SetupCopyFiles, COPY_$1_CMDS_DEBUGINFO_$m, \
|
||||
SRC := $(SUPPORT_OUTPUTDIR)/modules_cmds/$m, \
|
||||
DEST := $($1_IMAGE_DIR)/$(CMDS_TARGET_SUBDIR), \
|
||||
FILES := $(filter-out $(FILTERED_PDBS), $(call FindDebuginfoFiles, \
|
||||
$(SUPPORT_OUTPUTDIR)/modules_cmds/$m)), \
|
||||
FILES := $(call FindDebuginfoFiles, \
|
||||
$(SUPPORT_OUTPUTDIR)/modules_cmds/$m), \
|
||||
)) \
|
||||
$(eval $1_TARGETS += $$(COPY_$1_CMDS_DEBUGINFO_$m)) \
|
||||
)
|
||||
|
||||
@@ -1053,6 +1053,9 @@ else
|
||||
# All modules include the main license files from java.base.
|
||||
$(JMOD_TARGETS): java.base-copy
|
||||
|
||||
# jdk.javadoc uses an internal copy of the main license files from java.base.
|
||||
jdk.javadoc-copy: java.base-copy
|
||||
|
||||
zip-security: $(filter jdk.crypto%, $(JAVA_TARGETS))
|
||||
|
||||
ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
|
||||
|
||||
@@ -178,7 +178,8 @@ ifeq ($(TEST_JOBS), 0)
|
||||
c = c * $(TEST_JOBS_FACTOR_JDL); \
|
||||
c = c * $(TEST_JOBS_FACTOR_MACHINE); \
|
||||
if (c < 1) c = 1; \
|
||||
printf "%.0f", c; \
|
||||
c = c + 0.5; \
|
||||
printf "%d", c; \
|
||||
}')
|
||||
endif
|
||||
|
||||
@@ -356,7 +357,7 @@ ExpandJtregPath = \
|
||||
# with test id: dir/Test.java#selection -> Test.java#selection -> .java#selection -> #selection
|
||||
# without: dir/Test.java -> Test.java -> .java -> <<empty string>>
|
||||
TestID = \
|
||||
$(subst .sh,,$(subst .html,,$(subst .java,,$(suffix $(notdir $1)))))
|
||||
$(subst .jasm,,$(subst .sh,,$(subst .html,,$(subst .java,,$(suffix $(notdir $1))))))
|
||||
|
||||
# The test id starting with a hash (#testid) will be stripped by all
|
||||
# evals in ParseJtregTestSelectionInner and will be reinserted by calling
|
||||
@@ -867,7 +868,7 @@ define SetupRunJtregTestBody
|
||||
$$(RM) -r $$($1_TEST_RESULTS_DIR)
|
||||
|
||||
$1_COMMAND_LINE := \
|
||||
$$(JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \
|
||||
$$(JTREG_JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \
|
||||
-Dprogram=jtreg -jar $$(JT_HOME)/lib/jtreg.jar \
|
||||
$$($1_JTREG_BASIC_OPTIONS) \
|
||||
-testjdk:$$(JDK_UNDER_TEST) \
|
||||
|
||||
@@ -122,6 +122,7 @@ $(eval $(call SetupVariable,JT_HOME))
|
||||
$(eval $(call SetupVariable,JDK_IMAGE_DIR,$(OUTPUTDIR)/images/jdk))
|
||||
$(eval $(call SetupVariable,TEST_IMAGE_DIR,$(OUTPUTDIR)/images/test))
|
||||
$(eval $(call SetupVariable,SYMBOLS_IMAGE_DIR,$(OUTPUTDIR)/images/symbols,NO_CHECK))
|
||||
$(eval $(call SetupVariable,JTREG_JDK,$(BOOT_JDK)))
|
||||
|
||||
# Provide default values for tools that we need
|
||||
$(eval $(call SetupVariable,MAKE,make,NO_CHECK))
|
||||
@@ -157,6 +158,10 @@ ifeq ($(UNAME_OS), CYGWIN)
|
||||
OPENJDK_TARGET_OS := windows
|
||||
OPENJDK_TARGET_OS_TYPE := windows
|
||||
OPENJDK_TARGET_OS_ENV := windows.cygwin
|
||||
else ifeq ($(UNAME_OS), MINGW64)
|
||||
OPENJDK_TARGET_OS := windows
|
||||
OPENJDK_TARGET_OS_TYPE := windows
|
||||
OPENJDK_TARGET_OS_ENV := windows.msys2
|
||||
else
|
||||
OPENJDK_TARGET_OS_TYPE:=unix
|
||||
ifeq ($(UNAME_OS), Linux)
|
||||
@@ -169,6 +174,9 @@ else
|
||||
OPENJDK_TARGET_OS_ENV := $(OPENJDK_TARGET_OS)
|
||||
endif
|
||||
|
||||
# Sanity check env detection
|
||||
$(info Detected target OS, type and env: [$(OPENJDK_TARGET_OS)] [$(OPENJDK_TARGET_OS_TYPE)] [$(OPENJDK_TARGET_OS_ENV)])
|
||||
|
||||
# Assume little endian unless otherwise specified
|
||||
OPENJDK_TARGET_CPU_ENDIAN := little
|
||||
|
||||
@@ -248,6 +256,7 @@ $(call CreateNewSpec, $(NEW_SPEC), \
|
||||
TOPDIR := $(TOPDIR), \
|
||||
OUTPUTDIR := $(OUTPUTDIR), \
|
||||
BOOT_JDK := $(BOOT_JDK), \
|
||||
JTREG_JDK := $(JTREG_JDK), \
|
||||
JT_HOME := $(JT_HOME), \
|
||||
JDK_IMAGE_DIR := $(JDK_IMAGE_DIR), \
|
||||
JCOV_IMAGE_DIR := $(JCOV_IMAGE_DIR), \
|
||||
|
||||
@@ -124,6 +124,8 @@ JAR := $(FIXPATH) $(JAR_CMD)
|
||||
JLINK := $(FIXPATH) $(JLINK_CMD)
|
||||
JMOD := $(FIXPATH) $(JMOD_CMD)
|
||||
|
||||
JTREG_JAVA := $(FIXPATH) $(JTREG_JDK)/bin/java $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
|
||||
|
||||
BUILD_JAVA := $(JDK_IMAGE_DIR)/bin/JAVA
|
||||
################################################################################
|
||||
# Some common tools. Assume most common name and no path.
|
||||
|
||||
@@ -87,9 +87,9 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
$(eval $(call SetupZipArchive,BUILD_JGSS_BIN_ZIP, \
|
||||
SRC := $(SUPPORT_OUTPUTDIR), \
|
||||
INCLUDE_FILES := modules_libs/java.security.jgss/w2k_lsa_auth.dll \
|
||||
modules_libs/java.security.jgss/w2k_lsa_auth.diz \
|
||||
modules_libs/java.security.jgss/w2k_lsa_auth.map \
|
||||
modules_libs/java.security.jgss/w2k_lsa_auth.pdb, \
|
||||
modules_libs/java.security.jgss/w2k_lsa_auth.dll.diz \
|
||||
modules_libs/java.security.jgss/w2k_lsa_auth.dll.map \
|
||||
modules_libs/java.security.jgss/w2k_lsa_auth.dll.pdb, \
|
||||
ZIP := $(IMAGES_OUTPUTDIR)/$(JGSS_ZIP_NAME)))
|
||||
|
||||
TARGETS += $(IMAGES_OUTPUTDIR)/$(JGSS_ZIP_NAME)
|
||||
|
||||
@@ -522,7 +522,7 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER],
|
||||
# do this on s390x also for libjvm (where serviceability agent is not supported)
|
||||
if test "x$ENABLE_LINKTIME_GC" = xtrue; then
|
||||
TOOLCHAIN_CFLAGS_JDK="$TOOLCHAIN_CFLAGS_JDK -ffunction-sections -fdata-sections"
|
||||
if test "x$OPENJDK_TARGET_CPU" = xs390x; then
|
||||
if test "x$OPENJDK_TARGET_CPU" = xs390x && test "x$DEBUG_LEVEL" == xrelease; then
|
||||
TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -ffunction-sections -fdata-sections"
|
||||
fi
|
||||
fi
|
||||
@@ -799,15 +799,6 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
|
||||
$1_TOOLCHAIN_CFLAGS="${$1_GCC6_CFLAGS}"
|
||||
|
||||
$1_WARNING_CFLAGS_JVM="-Wno-format-zero-length -Wtype-limits -Wuninitialized"
|
||||
elif test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
NO_DELETE_NULL_POINTER_CHECKS_CFLAG="-fno-delete-null-pointer-checks"
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$NO_DELETE_NULL_POINTER_CHECKS_CFLAG],
|
||||
PREFIX: $3,
|
||||
IF_FALSE: [
|
||||
NO_DELETE_NULL_POINTER_CHECKS_CFLAG=
|
||||
]
|
||||
)
|
||||
$1_TOOLCHAIN_CFLAGS="${NO_DELETE_NULL_POINTER_CHECKS_CFLAG}"
|
||||
fi
|
||||
|
||||
if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||
@@ -852,6 +843,22 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
|
||||
FILE_MACRO_CFLAGS=
|
||||
]
|
||||
)
|
||||
if test "x$FILE_MACRO_CFLAGS" != x; then
|
||||
# Add -pathmap for all VS system include paths using Windows
|
||||
# full Long path name that is generated by the compiler
|
||||
# Not enabled under WSL as there is no easy way to obtain the
|
||||
# Windows full long paths, thus reproducible WSL builds will
|
||||
# depend on building with the same VS toolchain install location.
|
||||
if test "x$OPENJDK_BUILD_OS_ENV" != "xwindows.wsl1" && test "x$OPENJDK_BUILD_OS_ENV" != "xwindows.wsl2"; then
|
||||
for ipath in ${$3SYSROOT_CFLAGS}; do
|
||||
if test "x${ipath:0:2}" == "x-I"; then
|
||||
ipath_path=${ipath#"-I"}
|
||||
UTIL_FIXUP_WIN_LONG_PATH(ipath_path)
|
||||
FILE_MACRO_CFLAGS="$FILE_MACRO_CFLAGS -pathmap:\"$ipath_path\"=vsi"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([how to prevent absolute paths in output])
|
||||
@@ -929,17 +936,12 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
|
||||
# $2 - Prefix for compiler variables (either BUILD_ or nothing).
|
||||
AC_DEFUN([FLAGS_SETUP_GCC6_COMPILER_FLAGS],
|
||||
[
|
||||
# These flags are required for GCC 6 builds as undefined behavior in OpenJDK code
|
||||
# runs afoul of the more aggressive versions of these optimizations.
|
||||
# Notably, value range propagation now assumes that the this pointer of C++
|
||||
# member functions is non-null.
|
||||
NO_DELETE_NULL_POINTER_CHECKS_CFLAG="-fno-delete-null-pointer-checks"
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$NO_DELETE_NULL_POINTER_CHECKS_CFLAG],
|
||||
PREFIX: $2, IF_FALSE: [NO_DELETE_NULL_POINTER_CHECKS_CFLAG=""])
|
||||
# This flag is required for GCC 6 builds as undefined behavior in OpenJDK code
|
||||
# runs afoul of the more aggressive versions of this optimization.
|
||||
NO_LIFETIME_DSE_CFLAG="-fno-lifetime-dse"
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$NO_LIFETIME_DSE_CFLAG],
|
||||
PREFIX: $2, IF_FALSE: [NO_LIFETIME_DSE_CFLAG=""])
|
||||
$1_GCC6_CFLAGS="${NO_DELETE_NULL_POINTER_CHECKS_CFLAG} ${NO_LIFETIME_DSE_CFLAG}"
|
||||
$1_GCC6_CFLAGS="${NO_LIFETIME_DSE_CFLAG}"
|
||||
])
|
||||
|
||||
AC_DEFUN_ONCE([FLAGS_SETUP_BRANCH_PROTECTION],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -128,16 +128,12 @@ AC_DEFUN([FLAGS_SETUP_MACOSX_VERSION],
|
||||
# The expected format for <version> is either nn.n.n or nn.nn.nn. See
|
||||
# /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/AvailabilityVersions.h
|
||||
|
||||
# MACOSX_VERSION_MIN specifies the lowest version of Macosx that the built
|
||||
# MACOSX_VERSION_MIN specifies the lowest version of macOS that the built
|
||||
# binaries should be compatible with, even if compiled on a newer version
|
||||
# of the OS. It currently has a hard coded value. Setting this also limits
|
||||
# exposure to API changes in header files. Bumping this is likely to
|
||||
# require code changes to build.
|
||||
if test "x$OPENJDK_TARGET_CPU_ARCH" = xaarch64; then
|
||||
MACOSX_VERSION_MIN=11.00.00
|
||||
else
|
||||
MACOSX_VERSION_MIN=10.12.0
|
||||
fi
|
||||
MACOSX_VERSION_MIN=11.00.00
|
||||
MACOSX_VERSION_MIN_NODOTS=${MACOSX_VERSION_MIN//\./}
|
||||
|
||||
AC_SUBST(MACOSX_VERSION_MIN)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -134,7 +134,8 @@ AC_DEFUN([LIB_BUILD_BINUTILS],
|
||||
BINUTILS_SRC="$with_binutils_src"
|
||||
UTIL_FIXUP_PATH(BINUTILS_SRC)
|
||||
|
||||
BINUTILS_DIR="$CONFIGURESUPPORT_OUTPUTDIR/binutils"
|
||||
BINUTILS_BUILD_DIR="$CONFIGURESUPPORT_OUTPUTDIR/binutils"
|
||||
BINUTILS_INSTALL_DIR="$CONFIGURESUPPORT_OUTPUTDIR/binutils-install"
|
||||
|
||||
if ! test -d $BINUTILS_SRC; then
|
||||
AC_MSG_ERROR([--with-binutils-src is not pointing to a directory])
|
||||
@@ -143,15 +144,15 @@ AC_DEFUN([LIB_BUILD_BINUTILS],
|
||||
AC_MSG_ERROR([--with-binutils-src does not look like a binutils source directory])
|
||||
fi
|
||||
|
||||
if ! test -d $BINUTILS_DIR; then
|
||||
$MKDIR -p $BINUTILS_DIR
|
||||
if ! test -d $BINUTILS_BUILD_DIR; then
|
||||
$MKDIR -p $BINUTILS_BUILD_DIR
|
||||
fi
|
||||
|
||||
if test -e $BINUTILS_DIR/bfd/libbfd.a && \
|
||||
test -e $BINUTILS_DIR/opcodes/libopcodes.a && \
|
||||
test -e $BINUTILS_DIR/libiberty/libiberty.a && \
|
||||
test -e $BINUTILS_DIR/zlib/libz.a; then
|
||||
AC_MSG_NOTICE([Found binutils binaries in binutils source directory -- not building])
|
||||
# We don't know the version, not checking for libsframe.a
|
||||
if test -e $BINUTILS_INSTALL_DIR/lib/libbfd.a && \
|
||||
test -e $BINUTILS_INSTALL_DIR/lib/libopcodes.a && \
|
||||
test -e $BINUTILS_INSTALL_DIR/lib/libiberty.a; then
|
||||
AC_MSG_NOTICE([Found binutils binaries in binutils install directory -- not building])
|
||||
else
|
||||
# On Windows, we cannot build with the normal Microsoft CL, but must instead use
|
||||
# a separate mingw toolchain.
|
||||
@@ -190,20 +191,26 @@ AC_DEFUN([LIB_BUILD_BINUTILS],
|
||||
binutils_cflags="$binutils_cflags $MACHINE_FLAG $JVM_PICFLAG $C_O_FLAG_NORM"
|
||||
|
||||
AC_MSG_NOTICE([Running binutils configure])
|
||||
AC_MSG_NOTICE([configure command line: cd $BINUTILS_DIR && $BINUTILS_SRC/configure --disable-nls CFLAGS="$binutils_cflags" CC="$binutils_cc" AR="$AR" $binutils_target])
|
||||
AC_MSG_NOTICE([configure command line: cd $BINUTILS_BUILD_DIR && $BINUTILS_SRC/configure --disable-werror --prefix=$BINUTILS_INSTALL_DIR --enable-install-libiberty --with-system-zlib --without-zstd --disable-nls CFLAGS="$binutils_cflags" CC="$binutils_cc" AR="$AR" $binutils_target])
|
||||
saved_dir=`pwd`
|
||||
cd "$BINUTILS_DIR"
|
||||
$BINUTILS_SRC/configure --disable-nls CFLAGS="$binutils_cflags" CC="$binutils_cc" AR="$AR" $binutils_target
|
||||
if test $? -ne 0 || ! test -e $BINUTILS_DIR/Makefile; then
|
||||
cd "$BINUTILS_BUILD_DIR"
|
||||
$BINUTILS_SRC/configure --disable-werror --prefix=$BINUTILS_INSTALL_DIR --enable-install-libiberty --with-system-zlib --without-zstd --disable-nls CFLAGS="$binutils_cflags" CC="$binutils_cc" AR="$AR" $binutils_target
|
||||
if test $? -ne 0 || ! test -e $BINUTILS_BUILD_DIR/Makefile; then
|
||||
AC_MSG_NOTICE([Automatic building of binutils failed on configure. Try building it manually])
|
||||
AC_MSG_ERROR([Cannot continue])
|
||||
fi
|
||||
AC_MSG_NOTICE([Running binutils make])
|
||||
$MAKE all-opcodes
|
||||
$MAKE all-opcodes all-libiberty
|
||||
if test $? -ne 0; then
|
||||
AC_MSG_NOTICE([Automatic building of binutils failed on make. Try building it manually])
|
||||
AC_MSG_ERROR([Cannot continue])
|
||||
fi
|
||||
AC_MSG_NOTICE([Running binutils make install])
|
||||
$MAKE install-opcodes install-libiberty
|
||||
if test $? -ne 0; then
|
||||
AC_MSG_NOTICE([Automatic building, install step, of binutils failed on make. Try building it manually])
|
||||
AC_MSG_ERROR([Cannot continue])
|
||||
fi
|
||||
cd $saved_dir
|
||||
AC_MSG_NOTICE([Building of binutils done])
|
||||
fi
|
||||
@@ -223,40 +230,66 @@ AC_DEFUN([LIB_SETUP_HSDIS_BINUTILS],
|
||||
|
||||
# We need the binutils static libs and includes.
|
||||
if test "x$with_binutils_src" != x; then
|
||||
# Try building the source first. If it succeeds, it sets $BINUTILS_DIR.
|
||||
# Try building the source first. If it succeeds, it sets $BINUTILS_INSTALL_DIR.
|
||||
LIB_BUILD_BINUTILS
|
||||
fi
|
||||
|
||||
if test "x$with_binutils" != x; then
|
||||
BINUTILS_DIR="$with_binutils"
|
||||
BINUTILS_INSTALL_DIR="$with_binutils"
|
||||
fi
|
||||
|
||||
binutils_system_error=""
|
||||
HSDIS_LDFLAGS=""
|
||||
HSDIS_LIBS=""
|
||||
if test "x$BINUTILS_DIR" = xsystem; then
|
||||
disasm_header="<dis-asm.h>"
|
||||
|
||||
if test "x$BINUTILS_INSTALL_DIR" = xsystem; then
|
||||
AC_CHECK_LIB(bfd, bfd_openr, [ HSDIS_LIBS="-lbfd" ], [ binutils_system_error="libbfd not found" ])
|
||||
AC_CHECK_LIB(opcodes, disassembler, [ HSDIS_LIBS="$HSDIS_LIBS -lopcodes" ], [ binutils_system_error="libopcodes not found" ])
|
||||
AC_CHECK_LIB(iberty, xmalloc, [ HSDIS_LIBS="$HSDIS_LIBS -liberty" ], [ binutils_system_error="libiberty not found" ])
|
||||
AC_CHECK_LIB(z, deflate, [ HSDIS_LIBS="$HSDIS_LIBS -lz" ], [ binutils_system_error="libz not found" ])
|
||||
# libiberty is not required on Ubuntu
|
||||
AC_CHECK_LIB(iberty, xmalloc, [ HSDIS_LIBS="$HSDIS_LIBS -liberty" ])
|
||||
AC_CHECK_LIB(sframe, frame, [ HSDIS_LIBS="$HSDIS_LIBS -lsframe" ], )
|
||||
HSDIS_CFLAGS="-DLIBARCH_$OPENJDK_TARGET_CPU_LEGACY_LIB"
|
||||
elif test "x$BINUTILS_DIR" != x; then
|
||||
if test -e $BINUTILS_DIR/bfd/libbfd.a && \
|
||||
test -e $BINUTILS_DIR/opcodes/libopcodes.a && \
|
||||
test -e $BINUTILS_DIR/libiberty/libiberty.a && \
|
||||
test -e $BINUTILS_DIR/zlib/libz.a; then
|
||||
HSDIS_CFLAGS="-DLIBARCH_$OPENJDK_TARGET_CPU_LEGACY_LIB"
|
||||
if test -n "$BINUTILS_SRC"; then
|
||||
HSDIS_CFLAGS="$HSDIS_CFLAGS -I$BINUTILS_SRC/include -I$BINUTILS_DIR/bfd"
|
||||
elif test "x$BINUTILS_INSTALL_DIR" != x; then
|
||||
disasm_header="\"$BINUTILS_INSTALL_DIR/include/dis-asm.h\""
|
||||
if test -e $BINUTILS_INSTALL_DIR/lib/libbfd.a && \
|
||||
test -e $BINUTILS_INSTALL_DIR/lib/libopcodes.a && \
|
||||
(test -e $BINUTILS_INSTALL_DIR/lib/libiberty.a || test -e $BINUTILS_INSTALL_DIR/lib64/libiberty.a); then
|
||||
HSDIS_CFLAGS="-DLIBARCH_$OPENJDK_TARGET_CPU_LEGACY_LIB -I$BINUTILS_INSTALL_DIR/include"
|
||||
|
||||
# libiberty ignores --libdir and may be installed in $BINUTILS_INSTALL_DIR/lib or $BINUTILS_INSTALL_DIR/lib64
|
||||
# depending on system setup
|
||||
LIBIBERTY_LIB=""
|
||||
if test -e $BINUTILS_INSTALL_DIR/lib/libiberty.a; then
|
||||
LIBIBERTY_LIB="$BINUTILS_INSTALL_DIR/lib/libiberty.a"
|
||||
else
|
||||
HSDIS_CFLAGS="$HSDIS_CFLAGS -I$BINUTILS_DIR/include -I$BINUTILS_DIR/bfd"
|
||||
LIBIBERTY_LIB="$BINUTILS_INSTALL_DIR/lib64/libiberty.a"
|
||||
fi
|
||||
HSDIS_LDFLAGS=""
|
||||
HSDIS_LIBS="$BINUTILS_DIR/bfd/libbfd.a $BINUTILS_DIR/opcodes/libopcodes.a $BINUTILS_DIR/libiberty/libiberty.a $BINUTILS_DIR/zlib/libz.a"
|
||||
HSDIS_LIBS="$BINUTILS_INSTALL_DIR/lib/libbfd.a $BINUTILS_INSTALL_DIR/lib/libopcodes.a $LIBIBERTY_LIB"
|
||||
# If we have libsframe add it.
|
||||
if test -e $BINUTILS_INSTALL_DIR/lib/libsframe.a; then
|
||||
HSDIS_LIBS="$HSDIS_LIBS $BINUTILS_INSTALL_DIR/lib/libsframe.a"
|
||||
fi
|
||||
AC_CHECK_LIB(z, deflate, [ HSDIS_LIBS="$HSDIS_LIBS -lz" ], AC_MSG_ERROR([libz not found]))
|
||||
else
|
||||
AC_MSG_ERROR(["$BINUTILS_INSTALL_DIR/lib[64] must contain libbfd.a, libopcodes.a and libiberty.a"])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([Checking binutils API])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include $disasm_header],[[void foo() {init_disassemble_info(0, 0, 0, 0);}]])],
|
||||
[
|
||||
AC_MSG_RESULT([New API])
|
||||
HSDIS_CFLAGS="$HSDIS_CFLAGS -DBINUTILS_NEW_API"
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT([Old API])
|
||||
]
|
||||
)
|
||||
|
||||
AC_MSG_CHECKING([for binutils to use with hsdis])
|
||||
case "x$BINUTILS_DIR" in
|
||||
case "x$BINUTILS_INSTALL_DIR" in
|
||||
xsystem)
|
||||
if test "x$OPENJDK_TARGET_OS" != xlinux; then
|
||||
AC_MSG_RESULT([invalid])
|
||||
@@ -279,10 +312,10 @@ AC_DEFUN([LIB_SETUP_HSDIS_BINUTILS],
|
||||
;;
|
||||
*)
|
||||
if test "x$HSDIS_LIBS" != x; then
|
||||
AC_MSG_RESULT([$BINUTILS_DIR])
|
||||
AC_MSG_RESULT([$BINUTILS_INSTALL_DIR])
|
||||
else
|
||||
AC_MSG_RESULT([invalid])
|
||||
AC_MSG_ERROR([$BINUTILS_DIR does not contain a proper binutils installation])
|
||||
AC_MSG_ERROR([$BINUTILS_INSTALL_DIR does not contain a proper binutils installation])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -227,12 +227,47 @@ AC_DEFUN_ONCE([LIB_TESTS_SETUP_JTREG],
|
||||
UTIL_FIXUP_PATH(JT_HOME)
|
||||
AC_SUBST(JT_HOME)
|
||||
|
||||
# Specify a JDK for running jtreg. Defaults to the BOOT_JDK.
|
||||
AC_ARG_WITH(jtreg-jdk, [AS_HELP_STRING([--with-jdk],
|
||||
[path to JDK for running jtreg @<:@BOOT_JDK@:>@])])
|
||||
|
||||
AC_MSG_CHECKING([for jtreg jdk])
|
||||
if test "x${with_jtreg_jdk}" != x; then
|
||||
if test "x${with_jtreg_jdk}" = xno; then
|
||||
AC_MSG_RESULT([no, jtreg jdk not specified])
|
||||
elif test "x${with_jtreg_jdk}" = xyes; then
|
||||
AC_MSG_RESULT([not specified])
|
||||
AC_MSG_ERROR([--with-jtreg-jdk needs a value])
|
||||
else
|
||||
JTREG_JDK="${with_jtreg_jdk}"
|
||||
AC_MSG_RESULT([$JTREG_JDK])
|
||||
UTIL_FIXUP_PATH(JTREG_JDK)
|
||||
if test ! -f "$JTREG_JDK/bin/java"; then
|
||||
AC_MSG_ERROR([Could not find jtreg java at $JTREG_JDK/bin/java])
|
||||
fi
|
||||
fi
|
||||
else
|
||||
JTREG_JDK="${BOOT_JDK}"
|
||||
AC_MSG_RESULT([no, using BOOT_JDK])
|
||||
fi
|
||||
|
||||
UTIL_FIXUP_PATH(JTREG_JDK)
|
||||
AC_SUBST([JTREG_JDK])
|
||||
# For use in the configure script
|
||||
JTREG_JAVA="$FIXPATH $JTREG_JDK/bin/java"
|
||||
|
||||
# Verify jtreg version
|
||||
if test "x$JT_HOME" != x; then
|
||||
AC_MSG_CHECKING([jtreg jar existence])
|
||||
if test ! -f "$JT_HOME/lib/jtreg.jar"; then
|
||||
AC_MSG_ERROR([Could not find jtreg jar at $JT_HOME/lib/jtreg.jar])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([jtreg version number])
|
||||
# jtreg -version looks like this: "jtreg 6.1+1-19"
|
||||
# Extract actual version part ("6.1" in this case)
|
||||
jtreg_version_full=`$JAVA -jar $JT_HOME/lib/jtreg.jar -version | $HEAD -n 1 | $CUT -d ' ' -f 2`
|
||||
jtreg_version_full=$($JTREG_JAVA -jar $JT_HOME/lib/jtreg.jar -version | $HEAD -n 1 | $CUT -d ' ' -f 2)
|
||||
|
||||
jtreg_version=${jtreg_version_full/%+*}
|
||||
AC_MSG_RESULT([$jtreg_version])
|
||||
|
||||
|
||||
@@ -108,12 +108,6 @@ AC_DEFUN([LIB_SETUP_JVM_LIBS],
|
||||
BASIC_JVM_LIBS_$1="$BASIC_JVM_LIBS_$1 -latomic"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Because RISC-V only has word-sized atomics, it requires libatomic where
|
||||
# other common architectures do not, so link libatomic by default.
|
||||
if test "x$OPENJDK_$1_OS" = xlinux && test "x$OPENJDK_$1_CPU" = xriscv64; then
|
||||
BASIC_JVM_LIBS_$1="$BASIC_JVM_LIBS_$1 -latomic"
|
||||
fi
|
||||
])
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -685,6 +685,9 @@ JAR = $(JAR_CMD)
|
||||
JLINK = $(JLINK_CMD)
|
||||
JMOD = $(JMOD_CMD)
|
||||
|
||||
JTREG_JDK := @JTREG_JDK@
|
||||
JTREG_JAVA = @FIXPATH@ $(JTREG_JDK)/bin/java $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
|
||||
|
||||
BUILD_JAVA_FLAGS := @BOOTCYCLE_JVM_ARGS_BIG@
|
||||
BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS)
|
||||
BUILD_JAVAC=@FIXPATH@ $(BUILD_JDK)/bin/javac
|
||||
|
||||
@@ -118,6 +118,24 @@ AC_DEFUN([UTIL_FIXUP_PATH],
|
||||
fi
|
||||
])
|
||||
|
||||
##############################################################################
|
||||
# Fixup path to be a Windows full long path
|
||||
# Note: Only supported with cygwin/msys2 (cygpath tool)
|
||||
AC_DEFUN([UTIL_FIXUP_WIN_LONG_PATH],
|
||||
[
|
||||
# Only process if variable expands to non-empty
|
||||
path="[$]$1"
|
||||
if test "x$path" != x; then
|
||||
if test "x$OPENJDK_BUILD_OS" = "xwindows"; then
|
||||
win_path=$($PATHTOOL -wl "$path")
|
||||
if test "x$win_path" != "x$path"; then
|
||||
$1="$win_path"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Check if the given file is a unix-style or windows-style executable, that is,
|
||||
# if it expects paths in unix-style or windows-style.
|
||||
|
||||
@@ -62,8 +62,8 @@ endif
|
||||
# Filter out jvmci specific modules if jvmci is disabled
|
||||
ifeq ($(INCLUDE_JVMCI), false)
|
||||
MODULES_FILTER += jdk.internal.vm.ci
|
||||
MODULES_FILTER += jdk.internal.vm.compiler
|
||||
MODULES_FILTER += jdk.internal.vm.compiler.management
|
||||
MODULES_FILTER += jdk.graal.compiler
|
||||
MODULES_FILTER += jdk.graal.compiler.management
|
||||
endif
|
||||
|
||||
# jpackage is only on windows, macosx, and linux
|
||||
|
||||
@@ -1073,13 +1073,13 @@ define SetupNativeCompilationBody
|
||||
ifneq ($$($1_TYPE), STATIC_LIBRARY)
|
||||
# Generate debuginfo files.
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
$1_EXTRA_LDFLAGS += -debug "-pdb:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).pdb" \
|
||||
"-map:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).map"
|
||||
$1_EXTRA_LDFLAGS += -debug "-pdb:$$($1_SYMBOLS_DIR)/$$($1_BASENAME).pdb" \
|
||||
"-map:$$($1_SYMBOLS_DIR)/$$($1_BASENAME).map"
|
||||
ifeq ($(SHIP_DEBUG_SYMBOLS), public)
|
||||
$1_EXTRA_LDFLAGS += "-pdbstripped:$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).stripped.pdb"
|
||||
$1_EXTRA_LDFLAGS += "-pdbstripped:$$($1_SYMBOLS_DIR)/$$($1_BASENAME).stripped.pdb"
|
||||
endif
|
||||
$1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).pdb \
|
||||
$$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).map
|
||||
$1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_BASENAME).pdb \
|
||||
$$($1_SYMBOLS_DIR)/$$($1_BASENAME).map
|
||||
|
||||
else ifeq ($(call isTargetOs, linux), true)
|
||||
$1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).debuginfo
|
||||
@@ -1127,7 +1127,11 @@ define SetupNativeCompilationBody
|
||||
$1 += $$($1_DEBUGINFO_FILES)
|
||||
|
||||
ifeq ($$($1_ZIP_EXTERNAL_DEBUG_SYMBOLS), true)
|
||||
$1_DEBUGINFO_ZIP := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).diz
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
$1_DEBUGINFO_ZIP := $$($1_SYMBOLS_DIR)/$$($1_BASENAME).diz
|
||||
else
|
||||
$1_DEBUGINFO_ZIP := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).diz
|
||||
endif
|
||||
$1 += $$($1_DEBUGINFO_ZIP)
|
||||
|
||||
# The dependency on TARGET is needed for debuginfo files
|
||||
|
||||
@@ -29,13 +29,13 @@ 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/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_linux-x64_bin.tar.gz
|
||||
LINUX_X64_BOOT_JDK_SHA256=bb863b2d542976d1ae4b7b81af3e78b1e4247a64644350b552d298d8dc5980dc
|
||||
LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk21/fd2272bbf8e04c3dbaee13770090416c/35/GPL/openjdk-21_linux-x64_bin.tar.gz
|
||||
LINUX_X64_BOOT_JDK_SHA256=a30c454a9bef8f46d5f1bf3122830014a8fbe7ac03b5f8729bc3add4b92a1d0a
|
||||
|
||||
MACOS_X64_BOOT_JDK_EXT=tar.gz
|
||||
MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_macos-x64_bin.tar.gz
|
||||
MACOS_X64_BOOT_JDK_SHA256=47cf960d9bb89dbe987535a389f7e26c42de7c984ef5108612d77c81aa8cc6a4
|
||||
MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk21/fd2272bbf8e04c3dbaee13770090416c/35/GPL/openjdk-21_macos-x64_bin.tar.gz
|
||||
MACOS_X64_BOOT_JDK_SHA256=af32e84c11009f72f783fdcdc9917efc277893988f097e198e2576875d1e88c1
|
||||
|
||||
WINDOWS_X64_BOOT_JDK_EXT=zip
|
||||
WINDOWS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_windows-x64_bin.zip
|
||||
WINDOWS_X64_BOOT_JDK_SHA256=c92fae5e42b9aecf444a66c8ec563c652f60b1e231dfdd33a4f5a3e3603058fb
|
||||
WINDOWS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk21/fd2272bbf8e04c3dbaee13770090416c/35/GPL/openjdk-21_windows-x64_bin.zip
|
||||
WINDOWS_X64_BOOT_JDK_SHA256=5434faaf029e66e7ce6e75770ca384de476750984a7d2881ef7686894c4b4944
|
||||
|
||||
@@ -390,8 +390,8 @@ var getJibProfilesCommon = function (input, data) {
|
||||
};
|
||||
};
|
||||
|
||||
common.boot_jdk_version = "20";
|
||||
common.boot_jdk_build_number = "36";
|
||||
common.boot_jdk_version = "21";
|
||||
common.boot_jdk_build_number = "35";
|
||||
common.boot_jdk_home = input.get("boot_jdk", "install_path") + "/jdk-"
|
||||
+ common.boot_jdk_version
|
||||
+ (input.build_os == "macosx" ? ".jdk/Contents/Home" : "");
|
||||
@@ -426,9 +426,14 @@ var getJibProfilesProfiles = function (input, common, data) {
|
||||
target_os: "linux",
|
||||
target_cpu: "x86",
|
||||
build_cpu: "x64",
|
||||
dependencies: ["devkit", "gtest"],
|
||||
configure_args: concat(common.configure_args_32bit,
|
||||
"--with-jvm-variants=minimal,server", "--with-zlib=system"),
|
||||
dependencies: ["devkit", "gtest", "libffi"],
|
||||
configure_args: concat(common.configure_args_32bit, [
|
||||
"--with-jvm-variants=minimal,server",
|
||||
"--with-zlib=system",
|
||||
"--with-libffi=" + input.get("libffi", "home_path"),
|
||||
"--enable-libffi-bundling",
|
||||
"--enable-fallback-linker"
|
||||
])
|
||||
},
|
||||
|
||||
"macosx-x64": {
|
||||
@@ -436,7 +441,7 @@ var getJibProfilesProfiles = function (input, common, data) {
|
||||
target_cpu: "x64",
|
||||
dependencies: ["devkit", "gtest", "pandoc"],
|
||||
configure_args: concat(common.configure_args_64bit, "--with-zlib=system",
|
||||
"--with-macosx-version-max=10.12.00",
|
||||
"--with-macosx-version-max=11.00.00",
|
||||
"--enable-compatible-cds-alignment",
|
||||
// Use system SetFile instead of the one in the devkit as the
|
||||
// devkit one may not work on Catalina.
|
||||
@@ -945,10 +950,7 @@ var getJibProfilesProfiles = function (input, common, data) {
|
||||
target_os: input.build_os,
|
||||
target_cpu: input.build_cpu,
|
||||
dependencies: [ "jtreg", "gnumake", "boot_jdk", "devkit", "jib" ],
|
||||
labels: "test",
|
||||
environment: {
|
||||
"JT_JAVA": common.boot_jdk_home
|
||||
}
|
||||
labels: "test"
|
||||
}
|
||||
};
|
||||
profiles = concatObjects(profiles, testOnlyProfiles);
|
||||
@@ -1084,7 +1086,7 @@ var getJibProfilesDependencies = function (input, common) {
|
||||
|
||||
var devkit_platform_revisions = {
|
||||
linux_x64: "gcc11.2.0-OL6.4+1.0",
|
||||
macosx: "Xcode12.4+1.1",
|
||||
macosx: "Xcode14.3.1+1.0",
|
||||
windows_x64: "VS2022-17.1.0+1.1",
|
||||
linux_aarch64: input.build_cpu == "x64" ? "gcc11.2.0-OL7.6+1.1" : "gcc11.2.0-OL7.6+1.0",
|
||||
linux_arm: "gcc8.2.0-Fedora27+1.0",
|
||||
|
||||
@@ -60,8 +60,8 @@ BOOT_MODULES= \
|
||||
# should carefully be considered if it should be upgradeable or not.
|
||||
UPGRADEABLE_PLATFORM_MODULES= \
|
||||
java.compiler \
|
||||
jdk.internal.vm.compiler \
|
||||
jdk.internal.vm.compiler.management \
|
||||
jdk.graal.compiler \
|
||||
jdk.graal.compiler.management \
|
||||
#
|
||||
|
||||
PLATFORM_MODULES= \
|
||||
|
||||
@@ -37,6 +37,6 @@ DEFAULT_VERSION_DATE=2024-03-19
|
||||
DEFAULT_VERSION_CLASSFILE_MAJOR=66 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
||||
DEFAULT_VERSION_CLASSFILE_MINOR=0
|
||||
DEFAULT_VERSION_DOCS_API_SINCE=11
|
||||
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="20 21 22"
|
||||
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="21 22"
|
||||
DEFAULT_JDK_SOURCE_TARGET_VERSION=22
|
||||
DEFAULT_PROMOTED_VERSION_PRE=ea
|
||||
|
||||
@@ -106,8 +106,8 @@ for ex in $EXCLUDE_DIRS; do
|
||||
done
|
||||
|
||||
echo "Copying Xcode.app..."
|
||||
echo rsync -rlH $INCLUDE_ARGS $EXCLUDE_ARGS "$XCODE_APP/." $DEVKIT_ROOT/Xcode.app/
|
||||
rsync -rlH $INCLUDE_ARGS $EXCLUDE_ARGS "$XCODE_APP/." $DEVKIT_ROOT/Xcode.app/
|
||||
echo rsync -rlH $INCLUDE_ARGS $EXCLUDE_ARGS "$XCODE_APP/." $DEVKIT_ROOT/Xcode
|
||||
rsync -rlH $INCLUDE_ARGS $EXCLUDE_ARGS "$XCODE_APP/." $DEVKIT_ROOT/Xcode
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -119,8 +119,8 @@ echo "Generating devkit.info..."
|
||||
rm -f $DEVKIT_ROOT/devkit.info
|
||||
echo-info "# This file describes to configure how to interpret the contents of this devkit"
|
||||
echo-info "DEVKIT_NAME=\"Xcode $XCODE_VERSION (devkit)\""
|
||||
echo-info "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:\$DEVKIT_ROOT/Xcode.app/Contents/Developer/usr/bin\""
|
||||
echo-info "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/$SDK_VERSION.sdk\""
|
||||
echo-info "DEVKIT_TOOLCHAIN_PATH=\"\$DEVKIT_ROOT/Xcode/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:\$DEVKIT_ROOT/Xcode/Contents/Developer/usr/bin\""
|
||||
echo-info "DEVKIT_SYSROOT=\"\$DEVKIT_ROOT/Xcode/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/$SDK_VERSION.sdk\""
|
||||
echo-info "DEVKIT_EXTRA_PATH=\"\$DEVKIT_TOOLCHAIN_PATH\""
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -133,6 +133,21 @@ ifeq ($(call check-jvm-feature, compiler2), true)
|
||||
ADLCFLAGS += -DARM=1
|
||||
endif
|
||||
|
||||
# Set ASSERT, NDEBUG and PRODUCT flags just like in JvmFlags.gmk
|
||||
ifeq ($(DEBUG_LEVEL), release)
|
||||
# release builds disable uses of assert macro from <assert.h>.
|
||||
ADLCFLAGS += -DNDEBUG
|
||||
# For hotspot, release builds differ internally between "optimized" and "product"
|
||||
# in that "optimize" does not define PRODUCT.
|
||||
ifneq ($(HOTSPOT_DEBUG_LEVEL), optimized)
|
||||
ADLCFLAGS += -DPRODUCT
|
||||
endif
|
||||
else ifeq ($(DEBUG_LEVEL), fastdebug)
|
||||
ADLCFLAGS += -DASSERT
|
||||
else ifeq ($(DEBUG_LEVEL), slowdebug)
|
||||
ADLCFLAGS += -DASSERT
|
||||
endif
|
||||
|
||||
##############################################################################
|
||||
# Concatenate all ad source files into a single file, which will be fed to
|
||||
# adlc. Also include a #line directive at the start of every included file
|
||||
|
||||
@@ -61,7 +61,7 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
$(eval $(call SetupCopyFiles, COPY_GTEST_PDB_$v, \
|
||||
SRC := $(HOTSPOT_OUTPUTDIR)/variant-$v/libjvm/gtest, \
|
||||
DEST := $(TEST_IMAGE_DIR)/hotspot/gtest/$v, \
|
||||
FILES := jvm.pdb gtestLauncher.pdb, \
|
||||
FILES := jvm.dll.pdb gtestLauncher.exe.pdb, \
|
||||
)) \
|
||||
$(eval TARGETS += $$(COPY_GTEST_PDB_$v)) \
|
||||
) \
|
||||
|
||||
@@ -329,7 +329,7 @@ class CompilerInterfaceVC10 extends CompilerInterface {
|
||||
addAttr(rv, "PrecompiledHeaderOutputFile", outDir+Util.sep+"vm.pch");
|
||||
addAttr(rv, "AssemblerListingLocation", outDir);
|
||||
addAttr(rv, "ObjectFileName", outDir+Util.sep);
|
||||
addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb");
|
||||
addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.dll.pdb");
|
||||
// Set /nologo option
|
||||
addAttr(rv, "SuppressStartupBanner", "true");
|
||||
// Surpass the default /Tc or /Tp.
|
||||
@@ -409,7 +409,7 @@ class CompilerInterfaceVC10 extends CompilerInterface {
|
||||
addAttr(rv, "OutputFile", outDll);
|
||||
addAttr(rv, "SuppressStartupBanner", "true");
|
||||
addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
|
||||
addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb");
|
||||
addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.dll.pdb");
|
||||
addAttr(rv, "SubSystem", "Windows");
|
||||
addAttr(rv, "BaseAddress", "0x8000000");
|
||||
addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib");
|
||||
|
||||
@@ -30,7 +30,6 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.*;
|
||||
import java.text.MessageFormat;
|
||||
import java.time.*;
|
||||
import java.util.*;
|
||||
import java.util.ResourceBundle.Control;
|
||||
@@ -92,6 +91,12 @@ public class CLDRConverter {
|
||||
static final String[] EMPTY_ZONE = {"", "", "", "", "", ""};
|
||||
static final String META_ETCUTC_ZONE_NAME = "ETC_UTC";
|
||||
|
||||
// constants used for TZDB short names
|
||||
private static final String NBSP = "\u00A0";
|
||||
private static final String STD = "std";
|
||||
private static final String DST = "dst";
|
||||
private static final String NO_SUBST = "-";
|
||||
|
||||
private static SupplementDataParseHandler handlerSuppl;
|
||||
private static LikelySubtagsParseHandler handlerLikelySubtags;
|
||||
private static WinZonesParseHandler handlerWinZones;
|
||||
@@ -123,6 +128,10 @@ public class CLDRConverter {
|
||||
static Map<String, String> pluralRules;
|
||||
static Map<String, String> dayPeriodRules;
|
||||
|
||||
// TZDB Short Names Map
|
||||
private static final Map<String, String> tzdbShortNamesMap = HashMap.newHashMap(512);
|
||||
private static final Map<String, String> tzdbSubstLetters = HashMap.newHashMap(512);
|
||||
|
||||
static enum DraftType {
|
||||
UNCONFIRMED,
|
||||
PROVISIONAL,
|
||||
@@ -284,6 +293,9 @@ public class CLDRConverter {
|
||||
pluralRules = generateRules(handlerPlurals);
|
||||
dayPeriodRules = generateRules(handlerDayPeriodRule);
|
||||
|
||||
// TZDB short names map
|
||||
generateTZDBShortNamesMap();
|
||||
|
||||
List<Bundle> bundles = readBundleList();
|
||||
convertBundles(bundles);
|
||||
|
||||
@@ -757,21 +769,25 @@ public class CLDRConverter {
|
||||
.orElse(tzid);
|
||||
Object data = map.get(TIMEZONE_ID_PREFIX + tzKey);
|
||||
|
||||
if (data instanceof String[]) {
|
||||
if (data instanceof String[] tznames) {
|
||||
// Hack for UTC. UTC is an alias to Etc/UTC in CLDR
|
||||
if (tzid.equals("Etc/UTC") && !map.containsKey(TIMEZONE_ID_PREFIX + "UTC")) {
|
||||
names.put(METAZONE_ID_PREFIX + META_ETCUTC_ZONE_NAME, data);
|
||||
names.put(METAZONE_ID_PREFIX + META_ETCUTC_ZONE_NAME, tznames);
|
||||
names.put(tzid, META_ETCUTC_ZONE_NAME);
|
||||
names.put("UTC", META_ETCUTC_ZONE_NAME);
|
||||
} else {
|
||||
names.put(tzid, data);
|
||||
// TZDB short names
|
||||
fillTZDBShortNames(tzid, tznames);
|
||||
names.put(tzid, tznames);
|
||||
}
|
||||
} else {
|
||||
String meta = handlerMetaZones.get(tzKey);
|
||||
if (meta != null) {
|
||||
String metaKey = METAZONE_ID_PREFIX + meta;
|
||||
data = map.get(metaKey);
|
||||
if (data instanceof String[]) {
|
||||
if (data instanceof String[] tznames) {
|
||||
// TZDB short names
|
||||
fillTZDBShortNames(tzid, tznames);
|
||||
// Keep the metazone prefix here.
|
||||
names.put(metaKey, data);
|
||||
names.put(tzid, meta);
|
||||
@@ -1184,6 +1200,8 @@ public class CLDRConverter {
|
||||
Files.createDirectories(Paths.get(DESTINATION_DIR, "windows", "conf"));
|
||||
Files.write(Paths.get(DESTINATION_DIR, "windows", "conf", "tzmappings"),
|
||||
handlerWinZones.keySet().stream()
|
||||
.filter(k -> k.endsWith(":001") ||
|
||||
!handlerWinZones.get(k).equals(handlerWinZones.get(k.replaceFirst(":\\w{2,3}$", ":001"))))
|
||||
.map(k -> k + ":" + handlerWinZones.get(k) + ":")
|
||||
.sorted(new Comparator<String>() {
|
||||
public int compare(String t1, String t2) {
|
||||
@@ -1244,6 +1262,125 @@ public class CLDRConverter {
|
||||
return covMap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates two maps from TZ database files, where they have usual abbreviation
|
||||
* of the time zone names as "FORMAT".
|
||||
*
|
||||
* `tzdbShortNamesMap` maps the time zone id, such as "America/Los_Angeles" to
|
||||
* its FORMAT and Rule which determines the substitution. In "America/Los_Angeles"
|
||||
* case, its FORMAT is "P%sT" and the Rule is "US". They are concatenated with
|
||||
* an NBSP, so the eventual mapping will be:
|
||||
*
|
||||
* "America/Los_Angeles" -> "P%sT<NBSP>US"
|
||||
*
|
||||
* The other map, `tzdbSubstLetters` maps the Rule to its substitution letters.
|
||||
* The key of the map is the Rule name, appended with "<NBSP>std" or "<NBSP>dst"
|
||||
* depending on the savings, e.g.,
|
||||
*
|
||||
* "US<NBSP>std" -> "S"
|
||||
* "US<NBSP>dst" -> "D"
|
||||
*
|
||||
* These two mappings resolve the short names for time zones in each type,
|
||||
* such as:
|
||||
*
|
||||
* Standard short name for "America/Los_Angeles" -> "PST"
|
||||
* DST short name for "America/Los_Angeles" -> "PDT"
|
||||
* Generic short name for "America/Los_Angeles" -> "PT"
|
||||
*/
|
||||
private static void generateTZDBShortNamesMap() throws IOException {
|
||||
Files.walk(Path.of(tzDataDir), 1, FileVisitOption.FOLLOW_LINKS)
|
||||
.filter(p -> p.toFile().isFile())
|
||||
.forEach(p -> {
|
||||
try {
|
||||
String zone = null;
|
||||
String rule = null;
|
||||
String format = null;
|
||||
for (var line : Files.readAllLines(p)) {
|
||||
if (line.contains("#STDOFF")) continue;
|
||||
line = line.replaceAll("[ \t]*#.*", "");
|
||||
|
||||
// Zone line
|
||||
if (line.startsWith("Zone")) {
|
||||
var zl = line.split("[ \t]+", -1);
|
||||
zone = zl[1];
|
||||
rule = zl[3];
|
||||
format = zl[4];
|
||||
} else {
|
||||
if (zone != null) {
|
||||
if (line.isBlank()) {
|
||||
tzdbShortNamesMap.put(zone, format + NBSP + rule);
|
||||
zone = null;
|
||||
rule = null;
|
||||
format = null;
|
||||
} else {
|
||||
var s = line.split("[ \t]+", -1);
|
||||
rule = s[2];
|
||||
format = s[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, ""));
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
throw new UncheckedIOException(ioe);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the TZDB short names if there is no name provided by the CLDR
|
||||
*/
|
||||
private static void fillTZDBShortNames(String tzid, String[] names) {
|
||||
var val = tzdbShortNamesMap.get(tzid);
|
||||
if (val != null) {
|
||||
var format = val.split(NBSP)[0];
|
||||
var rule = val.split(NBSP)[1];
|
||||
IntStream.of(1, 3, 5).forEach(i -> {
|
||||
if (names[i] == null) {
|
||||
if (format.contains("%s")) {
|
||||
names[i] = switch (i) {
|
||||
case 1 -> format.formatted(tzdbSubstLetters.get(rule + NBSP + STD));
|
||||
case 3 -> format.formatted(tzdbSubstLetters.get(rule + NBSP + DST));
|
||||
case 5 -> format.formatted("");
|
||||
default -> throw new InternalError();
|
||||
};
|
||||
} else if (format.contains("/")) { // such as "+08/+09" or "GMT/BST"
|
||||
names[i] = switch (i) {
|
||||
case 1, 5 -> convertGMTName(format.substring(0, format.indexOf("/")));
|
||||
case 3 -> convertGMTName(format.substring(format.indexOf("/") + 1));
|
||||
default -> throw new InternalError();
|
||||
};
|
||||
} else {
|
||||
names[i] = convertGMTName(format);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert TZDB offsets to JDK's offsets, eg, "-08" to "GMT-08:00".
|
||||
* If it cannot recognize the pattern, return the argument as is.
|
||||
*/
|
||||
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);
|
||||
return null;
|
||||
} catch (DateTimeException dte) {
|
||||
// textual representation. return as is
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
// for debug
|
||||
static void dumpMap(Map<String, Object> map) {
|
||||
map.entrySet().stream()
|
||||
|
||||
@@ -51,9 +51,9 @@ import javacserver.util.Log;
|
||||
public class Client {
|
||||
private static final Log.Level LOG_LEVEL = Log.Level.INFO;
|
||||
|
||||
// Wait 2 seconds for response, before giving up on javac server.
|
||||
private static final int CONNECTION_TIMEOUT = 2000;
|
||||
private static final int MAX_CONNECT_ATTEMPTS = 3;
|
||||
// Wait 4 seconds for response, before giving up on javac server.
|
||||
private static final int CONNECTION_TIMEOUT = 4000;
|
||||
private static final int MAX_CONNECT_ATTEMPTS = 10;
|
||||
private static final int WAIT_BETWEEN_CONNECT_ATTEMPTS = 2000;
|
||||
|
||||
private final ClientConfiguration conf;
|
||||
@@ -130,7 +130,7 @@ public class Client {
|
||||
Log.error("Connection attempt failed: " + ex.getMessage());
|
||||
if (attempt >= MAX_CONNECT_ATTEMPTS) {
|
||||
Log.error("Giving up");
|
||||
throw new IOException("Could not connect to server", ex);
|
||||
throw new IOException("Could not connect to server after " + MAX_CONNECT_ATTEMPTS + " attempts with timeout " + CONNECTION_TIMEOUT, ex);
|
||||
}
|
||||
}
|
||||
Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
# questions.
|
||||
#
|
||||
|
||||
DISABLED_WARNINGS_java += this-escape
|
||||
DISABLED_WARNINGS_java += this-escape restricted
|
||||
|
||||
DOCLINT += -Xdoclint:all/protected \
|
||||
'-Xdoclint/package:java.*,javax.*'
|
||||
|
||||
@@ -234,3 +234,23 @@ ifeq ($(ENABLE_FALLBACK_LINKER), true)
|
||||
|
||||
TARGETS += $(BUILD_LIBFALLBACKLINKER)
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
|
||||
ifeq ($(call isTargetOs, linux)+$(call isTargetCpu, x86_64)+$(INCLUDE_COMPILER2)+$(filter $(TOOLCHAIN_TYPE), gcc), true+true+true+gcc)
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIB_SIMD_SORT, \
|
||||
NAME := simdsort, \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
OPTIMIZATION := HIGH, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB), \
|
||||
CXXFLAGS := $(CXXFLAGS_JDKLIB), \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LIBS := $(LIBCXX), \
|
||||
LIBS_linux := -lc -lm -ldl, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIB_SIMD_SORT)
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
|
||||
@@ -495,6 +495,11 @@ else
|
||||
# hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later.
|
||||
LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc
|
||||
|
||||
# list of disabled warnings and the compilers for which it was specifically added.
|
||||
# array-bounds -> GCC 12 on Alpine Linux
|
||||
# parentheses -> GCC 6
|
||||
# range-loop-analysis -> clang on Xcode12
|
||||
|
||||
HARFBUZZ_DISABLED_WARNINGS_gcc := missing-field-initializers strict-aliasing \
|
||||
unused-result array-bounds parentheses
|
||||
# noexcept-type required for GCC 7 builds. Not required for GCC 8+.
|
||||
@@ -919,19 +924,6 @@ endif
|
||||
|
||||
################################################################################
|
||||
|
||||
# MACOSX_METAL_VERSION_MIN specifies the lowest version of Macosx
|
||||
# that should be used to compile Metal shaders. We support Metal
|
||||
# pipeline only on Macosx >=10.14. For Macosx versions <10.14 even if
|
||||
# we enable Metal pipeline using -Dsun.java2d.metal=true, at
|
||||
# runtime we force it to use OpenGL pipeline. And MACOSX_VERSION_MIN
|
||||
# for aarch64 has always been >10.14 so we use continue to use
|
||||
# MACOSX_VERSION_MIN for aarch64.
|
||||
ifeq ($(OPENJDK_TARGET_CPU_ARCH), xaarch64)
|
||||
MACOSX_METAL_VERSION_MIN=$(MACOSX_VERSION_MIN)
|
||||
else
|
||||
MACOSX_METAL_VERSION_MIN=10.14.0
|
||||
endif
|
||||
|
||||
ifeq ($(call isTargetOs, macosx), true)
|
||||
SHADERS_SRC := $(TOPDIR)/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/shaders.metal
|
||||
SHADERS_SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/native/java.desktop/libosxui
|
||||
@@ -944,7 +936,7 @@ ifeq ($(call isTargetOs, macosx), true)
|
||||
OUTPUT_FILE := $(SHADERS_AIR), \
|
||||
SUPPORT_DIR := $(SHADERS_SUPPORT_DIR), \
|
||||
COMMAND := $(METAL) -c -std=osx-metal2.0 \
|
||||
-mmacosx-version-min=$(MACOSX_METAL_VERSION_MIN) \
|
||||
-mmacosx-version-min=$(MACOSX_VERSION_MIN) \
|
||||
-o $(SHADERS_AIR) $(SHADERS_SRC), \
|
||||
))
|
||||
|
||||
|
||||
47
make/modules/jdk.javadoc/Copy.gmk
Normal file
47
make/modules/jdk.javadoc/Copy.gmk
Normal file
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
include CopyCommon.gmk
|
||||
|
||||
JDK_JAVADOC_DIR := $(JDK_OUTPUTDIR)/modules/jdk.javadoc
|
||||
JDK_JAVADOC_DOCLET_RESOURCE_DIR := $(JDK_JAVADOC_DIR)/jdk/javadoc/internal/doclets/formats/html/resources
|
||||
|
||||
################################################################################
|
||||
|
||||
$(eval $(call SetupCopyFiles, COPY_JAVADOC_MODULE_LEGAL_RESOURCES, \
|
||||
DEST := $(JDK_JAVADOC_DOCLET_RESOURCE_DIR)/legal, \
|
||||
FILES := $(wildcard $(MODULE_SRC)/share/legal/*.md), \
|
||||
))
|
||||
TARGETS += $(COPY_JAVADOC_MODULE_LEGAL_RESOURCES)
|
||||
|
||||
################################################################################
|
||||
|
||||
$(eval $(call SetupCopyFiles, COPY_JAVADOC_COMMON_LEGAL_RESOURCES, \
|
||||
DEST := $(JDK_JAVADOC_DOCLET_RESOURCE_DIR)/legal, \
|
||||
FILES := $(wildcard $(COMMON_LEGAL_DST_DIR)/*), \
|
||||
))
|
||||
TARGETS += $(COPY_JAVADOC_COMMON_LEGAL_RESOURCES)
|
||||
|
||||
################################################################################
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -36,6 +36,7 @@ TARGETS += $(GENSRC_LOCALEDATA)
|
||||
CLDR_DATA_DIR := $(TOPDIR)/make/data/cldr/common
|
||||
GENSRC_DIR := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.localedata
|
||||
CLDR_GEN_DONE := $(GENSRC_DIR)/_cldr-gensrc.marker
|
||||
TZ_DATA_DIR := $(TOPDIR)/src/java.base/share/data/tzdata
|
||||
|
||||
$(CLDR_GEN_DONE): $(wildcard $(CLDR_DATA_DIR)/dtd/*.dtd) \
|
||||
$(wildcard $(CLDR_DATA_DIR)/main/*.xml) \
|
||||
@@ -47,7 +48,8 @@ $(CLDR_GEN_DONE): $(wildcard $(CLDR_DATA_DIR)/dtd/*.dtd) \
|
||||
$(TOOL_CLDRCONVERTER) -base $(CLDR_DATA_DIR) \
|
||||
-baselocales "en-US" \
|
||||
-year $(COPYRIGHT_YEAR) \
|
||||
-o $(GENSRC_DIR))
|
||||
-o $(GENSRC_DIR) \
|
||||
-tzdatadir $(TZ_DATA_DIR))
|
||||
$(TOUCH) $@
|
||||
|
||||
TARGETS += $(CLDR_GEN_DONE)
|
||||
|
||||
@@ -49,8 +49,8 @@ elif [ "$OPENJDK_TARGET_OS" = "windows" ]; then
|
||||
SKIP_BIN_DIFF="true"
|
||||
SKIP_FULLDUMP_DIFF="true"
|
||||
ACCEPTED_JARZIP_CONTENTS="
|
||||
/modules_libs/java.security.jgss/w2k_lsa_auth.pdb
|
||||
/modules_libs/java.security.jgss/w2k_lsa_auth.map
|
||||
/modules_libs/java.security.jgss/w2k_lsa_auth.dll.pdb
|
||||
/modules_libs/java.security.jgss/w2k_lsa_auth.dll.map
|
||||
/modules_libs/java.security.jgss/w2k_lsa_auth.dll
|
||||
"
|
||||
elif [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
|
||||
|
||||
@@ -84,14 +84,16 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \
|
||||
#### Compile Targets
|
||||
|
||||
# Building microbenchmark requires the jdk.unsupported and java.management modules.
|
||||
# sun.security.util is required to compile Cache benchmark
|
||||
# sun.security.util is required to compile Cache benchmark.
|
||||
# jmh uses annotation processors to generate the benchmark jar and thus
|
||||
# requires the use of -processor option during benchmark compilation.
|
||||
|
||||
# Build microbenchmark suite for the current JDK
|
||||
$(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \
|
||||
TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \
|
||||
SMALL_JAVA := false, \
|
||||
CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \
|
||||
DISABLED_WARNINGS := this-escape processing rawtypes cast serial preview, \
|
||||
DISABLED_WARNINGS := restricted this-escape processing rawtypes cast serial preview, \
|
||||
SRC := $(MICROBENCHMARK_SRC), \
|
||||
BIN := $(MICROBENCHMARK_CLASSES), \
|
||||
JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \
|
||||
@@ -105,8 +107,11 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.vm=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.event=ALL-UNNAMED \
|
||||
--enable-preview, \
|
||||
--add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \
|
||||
--enable-preview \
|
||||
-processor org.openjdk.jmh.generators.BenchmarkProcessor, \
|
||||
JAVA_FLAGS := --add-modules jdk.unsupported --limit-modules java.management \
|
||||
--add-exports java.base/jdk.internal.vm=ALL-UNNAMED \
|
||||
--enable-preview, \
|
||||
|
||||
@@ -16420,10 +16420,10 @@ instruct branchLoopEnd(cmpOp cmp, rFlagsReg cr, label lbl)
|
||||
// ============================================================================
|
||||
// inlined locking and unlocking
|
||||
|
||||
instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2)
|
||||
instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegPNoSp tmp2, iRegPNoSp tmp3)
|
||||
%{
|
||||
match(Set cr (FastLock object box));
|
||||
effect(TEMP tmp, TEMP tmp2);
|
||||
effect(TEMP tmp, TEMP tmp2, TEMP tmp3);
|
||||
|
||||
// TODO
|
||||
// identify correct cost
|
||||
@@ -16431,7 +16431,7 @@ instruct cmpFastLock(rFlagsReg cr, iRegP object, iRegP box, iRegPNoSp tmp, iRegP
|
||||
format %{ "fastlock $object,$box\t! kills $tmp,$tmp2" %}
|
||||
|
||||
ins_encode %{
|
||||
__ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register);
|
||||
__ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $tmp2$$Register, $tmp3$$Register);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
|
||||
@@ -434,7 +434,7 @@ int LIR_Assembler::emit_unwind_handler() {
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
__ b(*stub->entry());
|
||||
} else {
|
||||
__ unlock_object(r5, r4, r0, *stub->entry());
|
||||
__ unlock_object(r5, r4, r0, r6, *stub->entry());
|
||||
}
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
@@ -2535,6 +2535,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
|
||||
Register obj = op->obj_opr()->as_register(); // may not be an oop
|
||||
Register hdr = op->hdr_opr()->as_register();
|
||||
Register lock = op->lock_opr()->as_register();
|
||||
Register temp = op->scratch_opr()->as_register();
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
if (op->info() != nullptr) {
|
||||
add_debug_info_for_null_check_here(op->info());
|
||||
@@ -2544,14 +2545,14 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
|
||||
} else if (op->code() == lir_lock) {
|
||||
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
|
||||
// add debug info for NullPointerException only if one is possible
|
||||
int null_check_offset = __ lock_object(hdr, obj, lock, *op->stub()->entry());
|
||||
int null_check_offset = __ lock_object(hdr, obj, lock, temp, *op->stub()->entry());
|
||||
if (op->info() != nullptr) {
|
||||
add_debug_info_for_null_check(null_check_offset, op->info());
|
||||
}
|
||||
// done
|
||||
} else if (op->code() == lir_unlock) {
|
||||
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
|
||||
__ unlock_object(hdr, obj, lock, *op->stub()->entry());
|
||||
__ unlock_object(hdr, obj, lock, temp, *op->stub()->entry());
|
||||
} else {
|
||||
Unimplemented();
|
||||
}
|
||||
|
||||
@@ -314,6 +314,7 @@ void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
|
||||
|
||||
// "lock" stores the address of the monitor stack slot, so this is not an oop
|
||||
LIR_Opr lock = new_register(T_INT);
|
||||
LIR_Opr scratch = new_register(T_INT);
|
||||
|
||||
CodeEmitInfo* info_for_exception = nullptr;
|
||||
if (x->needs_null_check()) {
|
||||
@@ -322,7 +323,7 @@ void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
|
||||
// this CodeEmitInfo must not have the xhandlers because here the
|
||||
// object is already locked (xhandlers expect object to be unlocked)
|
||||
CodeEmitInfo* info = state_for(x, x->state(), true);
|
||||
monitor_enter(obj.result(), lock, syncTempOpr(), LIR_OprFact::illegalOpr,
|
||||
monitor_enter(obj.result(), lock, syncTempOpr(), scratch,
|
||||
x->monitor_no(), info_for_exception, info);
|
||||
}
|
||||
|
||||
@@ -335,8 +336,9 @@ void LIRGenerator::do_MonitorExit(MonitorExit* x) {
|
||||
|
||||
LIR_Opr lock = new_register(T_INT);
|
||||
LIR_Opr obj_temp = new_register(T_INT);
|
||||
LIR_Opr scratch = new_register(T_INT);
|
||||
set_no_result(x);
|
||||
monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no());
|
||||
monitor_exit(obj_temp, lock, syncTempOpr(), scratch, x->monitor_no());
|
||||
}
|
||||
|
||||
void LIRGenerator::do_NegateOp(NegateOp* x) {
|
||||
|
||||
@@ -60,10 +60,10 @@ void C1_MacroAssembler::float_cmp(bool is_float, int unordered_result,
|
||||
}
|
||||
}
|
||||
|
||||
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
|
||||
int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
|
||||
const int aligned_mask = BytesPerWord -1;
|
||||
const int hdr_offset = oopDesc::mark_offset_in_bytes();
|
||||
assert_different_registers(hdr, obj, disp_hdr);
|
||||
assert_different_registers(hdr, obj, disp_hdr, temp, rscratch2);
|
||||
int null_check_offset = -1;
|
||||
|
||||
verify_oop(obj);
|
||||
@@ -83,7 +83,7 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
|
||||
// Load object header
|
||||
ldr(hdr, Address(obj, hdr_offset));
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
lightweight_lock(obj, hdr, rscratch1, rscratch2, slow_case);
|
||||
lightweight_lock(obj, hdr, temp, rscratch2, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
Label done;
|
||||
// and mark it as unlocked
|
||||
@@ -125,10 +125,10 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
|
||||
}
|
||||
|
||||
|
||||
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
|
||||
void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
|
||||
const int aligned_mask = BytesPerWord -1;
|
||||
const int hdr_offset = oopDesc::mark_offset_in_bytes();
|
||||
assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different");
|
||||
assert_different_registers(hdr, obj, disp_hdr, temp, rscratch2);
|
||||
Label done;
|
||||
|
||||
if (LockingMode != LM_LIGHTWEIGHT) {
|
||||
@@ -149,7 +149,7 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_
|
||||
// be encoded.
|
||||
tst(hdr, markWord::monitor_value);
|
||||
br(Assembler::NE, slow_case);
|
||||
lightweight_unlock(obj, hdr, rscratch1, rscratch2, slow_case);
|
||||
lightweight_unlock(obj, hdr, temp, rscratch2, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// test if object header is pointing to the displaced header, and if so, restore
|
||||
// the displaced header in the object - if the object header is not pointing to
|
||||
|
||||
@@ -58,14 +58,16 @@ using MacroAssembler::null_check;
|
||||
// hdr : must be r0, contents destroyed
|
||||
// obj : must point to the object to lock, contents preserved
|
||||
// disp_hdr: must point to the displaced header location, contents preserved
|
||||
// temp : temporary register, must not be rscratch1 or rscratch2
|
||||
// returns code offset at which to add null check debug information
|
||||
int lock_object (Register swap, Register obj, Register disp_hdr, Label& slow_case);
|
||||
int lock_object (Register swap, Register obj, Register disp_hdr, Register temp, Label& slow_case);
|
||||
|
||||
// unlocking
|
||||
// hdr : contents destroyed
|
||||
// obj : must point to the object to lock, contents preserved
|
||||
// disp_hdr: must be r0 & must point to the displaced header location, contents destroyed
|
||||
void unlock_object(Register swap, Register obj, Register lock, Label& slow_case);
|
||||
// temp : temporary register, must not be rscratch1 or rscratch2
|
||||
void unlock_object(Register swap, Register obj, Register lock, Register temp, Label& slow_case);
|
||||
|
||||
void initialize_object(
|
||||
Register obj, // result: pointer to object after successful allocation
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr);
|
||||
|
||||
void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register tmpReg,
|
||||
Register tmp2Reg) {
|
||||
Register tmp2Reg, Register tmp3Reg) {
|
||||
Register oop = objectReg;
|
||||
Register box = boxReg;
|
||||
Register disp_hdr = tmpReg;
|
||||
@@ -104,7 +104,7 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
|
||||
b(cont);
|
||||
} else {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
lightweight_lock(oop, disp_hdr, tmp, rscratch1, no_count);
|
||||
lightweight_lock(oop, disp_hdr, tmp, tmp3Reg, no_count);
|
||||
b(count);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
|
||||
// Try to CAS m->owner from NULL to current thread.
|
||||
add(tmp, disp_hdr, (in_bytes(ObjectMonitor::owner_offset())-markWord::monitor_value));
|
||||
cmpxchg(tmp, zr, rthread, Assembler::xword, /*acquire*/ true,
|
||||
/*release*/ true, /*weak*/ false, rscratch1); // Sets flags for result
|
||||
/*release*/ true, /*weak*/ false, tmp3Reg); // Sets flags for result
|
||||
|
||||
if (LockingMode != LM_LIGHTWEIGHT) {
|
||||
// Store a non-null value into the box to avoid looking like a re-entrant
|
||||
@@ -129,7 +129,7 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
|
||||
}
|
||||
br(Assembler::EQ, cont); // CAS success means locking succeeded
|
||||
|
||||
cmp(rscratch1, rthread);
|
||||
cmp(tmp3Reg, rthread);
|
||||
br(Assembler::NE, cont); // Check for recursive locking
|
||||
|
||||
// Recursive lock case
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
public:
|
||||
// Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file.
|
||||
// See full description in macroAssembler_aarch64.cpp.
|
||||
void fast_lock(Register object, Register box, Register tmp, Register tmp2);
|
||||
void fast_lock(Register object, Register box, Register tmp, Register tmp2, Register tmp3);
|
||||
void fast_unlock(Register object, Register box, Register tmp, Register tmp2);
|
||||
|
||||
void string_compare(Register str1, Register str2,
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
|
||||
frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc);
|
||||
|
||||
frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb);
|
||||
frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, bool allow_cb_null = false);
|
||||
// used for fast frame construction by continuations
|
||||
frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map, bool on_heap);
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
|
||||
init(sp, fp, pc);
|
||||
}
|
||||
|
||||
inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb) {
|
||||
inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, bool allow_cb_null) {
|
||||
assert(pauth_ptr_is_raw(pc), "cannot be signed");
|
||||
intptr_t a = intptr_t(sp);
|
||||
intptr_t b = intptr_t(fp);
|
||||
@@ -102,7 +102,7 @@ inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address
|
||||
assert(pc != nullptr, "no pc?");
|
||||
_cb = cb;
|
||||
_oop_map = nullptr;
|
||||
assert(_cb != nullptr, "pc: " INTPTR_FORMAT, p2i(pc));
|
||||
assert(_cb != nullptr || allow_cb_null, "pc: " INTPTR_FORMAT, p2i(pc));
|
||||
_on_heap = false;
|
||||
DEBUG_ONLY(_frame_index = -1;)
|
||||
|
||||
|
||||
@@ -734,7 +734,7 @@ void InterpreterMacroAssembler::remove_activation(
|
||||
//
|
||||
// Kills:
|
||||
// r0
|
||||
// c_rarg0, c_rarg1, c_rarg2, c_rarg3, .. (param regs)
|
||||
// c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, .. (param regs)
|
||||
// rscratch1, rscratch2 (scratch regs)
|
||||
void InterpreterMacroAssembler::lock_object(Register lock_reg)
|
||||
{
|
||||
@@ -749,6 +749,8 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
|
||||
const Register swap_reg = r0;
|
||||
const Register tmp = c_rarg2;
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp2 = c_rarg4;
|
||||
const Register tmp3 = c_rarg5;
|
||||
|
||||
const int obj_offset = in_bytes(BasicObjectLock::obj_offset());
|
||||
const int lock_offset = in_bytes(BasicObjectLock::lock_offset());
|
||||
@@ -769,7 +771,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
|
||||
|
||||
if (LockingMode == LM_LIGHTWEIGHT) {
|
||||
ldr(tmp, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
lightweight_lock(obj_reg, tmp, rscratch1, rscratch2, slow_case);
|
||||
lightweight_lock(obj_reg, tmp, tmp2, tmp3, slow_case);
|
||||
b(count);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// Load (object->mark() | 1) into swap_reg
|
||||
@@ -867,6 +869,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
|
||||
const Register swap_reg = r0;
|
||||
const Register header_reg = c_rarg2; // Will contain the old oopMark
|
||||
const Register obj_reg = c_rarg3; // Will contain the oop
|
||||
const Register tmp_reg = c_rarg4; // Temporary used by lightweight_unlock
|
||||
|
||||
save_bcp(); // Save in case of exception
|
||||
|
||||
@@ -900,7 +903,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
|
||||
|
||||
ldr(header_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
tbnz(header_reg, exact_log2(markWord::monitor_value), slow_case);
|
||||
lightweight_unlock(obj_reg, header_reg, swap_reg, rscratch1, slow_case);
|
||||
lightweight_unlock(obj_reg, header_reg, swap_reg, tmp_reg, slow_case);
|
||||
b(count);
|
||||
bind(slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
|
||||
@@ -2839,6 +2839,10 @@ void MacroAssembler::cmpxchg(Register addr, Register expected,
|
||||
mov(result, expected);
|
||||
lse_cas(result, new_val, addr, size, acquire, release, /*not_pair*/ true);
|
||||
compare_eq(result, expected, size);
|
||||
#ifdef ASSERT
|
||||
// Poison rscratch1 which is written on !UseLSE branch
|
||||
mov(rscratch1, 0x1f1f1f1f1f1f1f1f);
|
||||
#endif
|
||||
} else {
|
||||
Label retry_load, done;
|
||||
prfm(Address(addr), PSTL1STRM);
|
||||
@@ -6315,7 +6319,7 @@ void MacroAssembler::double_move(VMRegPair src, VMRegPair dst, Register tmp) {
|
||||
// - t1, t2: temporary registers, will be destroyed
|
||||
void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register t1, Register t2, Label& slow) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking");
|
||||
assert_different_registers(obj, hdr, t1, t2);
|
||||
assert_different_registers(obj, hdr, t1, t2, rscratch1);
|
||||
|
||||
// Check if we would have space on lock-stack for the object.
|
||||
ldrw(t1, Address(rthread, JavaThread::lock_stack_top_offset()));
|
||||
@@ -6327,6 +6331,7 @@ void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register t1, R
|
||||
// Clear lock-bits, into t2
|
||||
eor(t2, hdr, markWord::unlocked_value);
|
||||
// Try to swing header from unlocked to locked
|
||||
// Clobbers rscratch1 when UseLSE is false
|
||||
cmpxchg(/*addr*/ obj, /*expected*/ hdr, /*new*/ t2, Assembler::xword,
|
||||
/*acquire*/ true, /*release*/ true, /*weak*/ false, t1);
|
||||
br(Assembler::NE, slow);
|
||||
@@ -6347,7 +6352,7 @@ void MacroAssembler::lightweight_lock(Register obj, Register hdr, Register t1, R
|
||||
// - t1, t2: temporary registers
|
||||
void MacroAssembler::lightweight_unlock(Register obj, Register hdr, Register t1, Register t2, Label& slow) {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "only used with new lightweight locking");
|
||||
assert_different_registers(obj, hdr, t1, t2);
|
||||
assert_different_registers(obj, hdr, t1, t2, rscratch1);
|
||||
|
||||
#ifdef ASSERT
|
||||
{
|
||||
@@ -6387,6 +6392,7 @@ void MacroAssembler::lightweight_unlock(Register obj, Register hdr, Register t1,
|
||||
orr(t1, hdr, markWord::unlocked_value);
|
||||
|
||||
// Try to swing header from locked to unlocked
|
||||
// Clobbers rscratch1 when UseLSE is false
|
||||
cmpxchg(obj, hdr, t1, Assembler::xword,
|
||||
/*acquire*/ true, /*release*/ true, /*weak*/ false, t2);
|
||||
br(Assembler::NE, slow);
|
||||
|
||||
@@ -1760,6 +1760,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
const Register obj_reg = r19; // Will contain the oop
|
||||
const Register lock_reg = r13; // Address of compiler lock object (BasicLock)
|
||||
const Register old_hdr = r13; // value of old header at unlock time
|
||||
const Register lock_tmp = r14; // Temporary used by lightweight_lock/unlock
|
||||
const Register tmp = lr;
|
||||
|
||||
Label slow_path_lock;
|
||||
@@ -1813,7 +1814,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
} else {
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "must be");
|
||||
__ ldr(swap_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
__ lightweight_lock(obj_reg, swap_reg, tmp, rscratch1, slow_path_lock);
|
||||
__ lightweight_lock(obj_reg, swap_reg, tmp, lock_tmp, slow_path_lock);
|
||||
}
|
||||
__ bind(count);
|
||||
__ increment(Address(rthread, JavaThread::held_monitor_count_offset()));
|
||||
@@ -1954,7 +1955,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
assert(LockingMode == LM_LIGHTWEIGHT, "");
|
||||
__ ldr(old_hdr, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
|
||||
__ tbnz(old_hdr, exact_log2(markWord::monitor_value), slow_path_unlock);
|
||||
__ lightweight_unlock(obj_reg, old_hdr, swap_reg, rscratch1, slow_path_unlock);
|
||||
__ lightweight_unlock(obj_reg, old_hdr, swap_reg, lock_tmp, slow_path_unlock);
|
||||
__ decrement(Address(rthread, JavaThread::held_monitor_count_offset()));
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/continuation.hpp"
|
||||
#include "runtime/continuationEntry.inline.hpp"
|
||||
@@ -7326,6 +7327,21 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
#endif // INCLUDE_JFR
|
||||
|
||||
// exception handler for upcall stubs
|
||||
address generate_upcall_stub_exception_handler() {
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
|
||||
address start = __ pc();
|
||||
|
||||
// Native caller has no idea how to handle exceptions,
|
||||
// so we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(r0);
|
||||
__ movptr(rscratch1, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception));
|
||||
__ blr(rscratch1);
|
||||
__ should_not_reach_here();
|
||||
|
||||
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
|
||||
@@ -8377,6 +8393,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
#endif // LINUX
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
|
||||
StubRoutines::aarch64::set_completed(); // Inidicate that arraycopy and zero_blocks stubs are generated
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ 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);
|
||||
@@ -233,9 +234,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
__ block_comment("{ receiver ");
|
||||
__ movptr(shuffle_reg, (intptr_t)receiver);
|
||||
__ resolve_jobject(shuffle_reg, rscratch1, rscratch2);
|
||||
__ mov(j_rarg0, shuffle_reg);
|
||||
__ get_vm_result(j_rarg0, rthread);
|
||||
__ block_comment("} receiver ");
|
||||
|
||||
__ mov_metadata(rmethod, entry);
|
||||
@@ -306,19 +305,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__ block_comment("{ exception handler");
|
||||
|
||||
intptr_t exception_handler_offset = __ pc() - start;
|
||||
|
||||
// Native caller has no idea how to handle exceptions,
|
||||
// so we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(r0);
|
||||
__ movptr(rscratch1, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception));
|
||||
__ blr(rscratch1);
|
||||
__ should_not_reach_here();
|
||||
|
||||
__ block_comment("} exception handler");
|
||||
|
||||
_masm->flush();
|
||||
|
||||
#ifndef PRODUCT
|
||||
@@ -334,7 +320,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
UpcallStub* blob
|
||||
= UpcallStub::create(name,
|
||||
&buffer,
|
||||
exception_handler_offset,
|
||||
receiver,
|
||||
in_ByteSize(frame_data_offset));
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "oops/markWord.hpp"
|
||||
#include "oops/method.hpp"
|
||||
#include "oops/methodData.hpp"
|
||||
#include "oops/resolvedFieldEntry.hpp"
|
||||
#include "oops/resolvedIndyEntry.hpp"
|
||||
#include "prims/jvmtiExport.hpp"
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
@@ -312,6 +313,36 @@ void InterpreterMacroAssembler::load_resolved_indy_entry(Register cache, Registe
|
||||
add(cache, cache, index);
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::load_field_entry(Register cache, Register index, int bcp_offset) {
|
||||
// Get index out of bytecode pointer
|
||||
assert_different_registers(cache, index);
|
||||
|
||||
get_index_at_bcp(index, bcp_offset, cache /*as tmp*/, sizeof(u2));
|
||||
|
||||
// Scale the index to be the entry index * sizeof(ResolvedFieldEntry)
|
||||
// sizeof(ResolvedFieldEntry) is 16 on Arm, so using shift
|
||||
if (is_power_of_2(sizeof(ResolvedFieldEntry))) {
|
||||
// load constant pool cache pointer
|
||||
ldr(cache, Address(FP, frame::interpreter_frame_cache_offset * wordSize));
|
||||
// Get address of field entries array
|
||||
ldr(cache, Address(cache, in_bytes(ConstantPoolCache::field_entries_offset())));
|
||||
|
||||
add(cache, cache, Array<ResolvedFieldEntry>::base_offset_in_bytes());
|
||||
add(cache, cache, AsmOperand(index, lsl, log2i_exact(sizeof(ResolvedFieldEntry))));
|
||||
}
|
||||
else {
|
||||
mov(cache, sizeof(ResolvedFieldEntry));
|
||||
mul(index, index, cache);
|
||||
// load constant pool cache pointer
|
||||
ldr(cache, Address(FP, frame::interpreter_frame_cache_offset * wordSize));
|
||||
|
||||
// Get address of field entries array
|
||||
ldr(cache, Address(cache, in_bytes(ConstantPoolCache::field_entries_offset())));
|
||||
add(cache, cache, Array<ResolvedFieldEntry>::base_offset_in_bytes());
|
||||
add(cache, cache, index);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a subtype check: branch to not_subtype if sub_klass is
|
||||
// not a subtype of super_klass.
|
||||
// Profiling code for the subtype check failure (profile_typecheck_failed)
|
||||
|
||||
@@ -102,6 +102,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
void load_resolved_klass_at_offset(Register Rcpool, Register Rindex, Register Rklass);
|
||||
|
||||
void load_resolved_indy_entry(Register cache, Register index);
|
||||
void load_field_entry(Register cache, Register index, int bcp_offset = 1);
|
||||
|
||||
void pop_ptr(Register r);
|
||||
void pop_i(Register r = R0_tos);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/resolvedIndyEntry.hpp"
|
||||
#include "oops/resolvedFieldEntry.hpp"
|
||||
#include "prims/jvmtiExport.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
@@ -227,7 +228,16 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
|
||||
// additional, required work.
|
||||
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
|
||||
assert(load_bc_into_bc_reg, "we use bc_reg as temp");
|
||||
__ get_cache_and_index_and_bytecode_at_bcp(bc_reg, temp_reg, temp_reg, byte_no, 1, sizeof(u2));
|
||||
__ load_field_entry(temp_reg, bc_reg);
|
||||
if (byte_no == f1_byte) {
|
||||
__ add(temp_reg, temp_reg, in_bytes(ResolvedFieldEntry::get_code_offset()));
|
||||
} else {
|
||||
__ add(temp_reg, temp_reg, in_bytes(ResolvedFieldEntry::put_code_offset()));
|
||||
}
|
||||
// Load-acquire the bytecode to match store-release in ResolvedFieldEntry::fill_in()
|
||||
__ ldrb(temp_reg, temp_reg);
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg, true);
|
||||
|
||||
__ mov(bc_reg, bc);
|
||||
__ cbz(temp_reg, L_patch_done); // test if bytecode is zero
|
||||
}
|
||||
@@ -2567,12 +2577,6 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
|
||||
|
||||
Label resolved;
|
||||
Bytecodes::Code code = bytecode();
|
||||
switch (code) {
|
||||
case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
|
||||
case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
|
||||
__ get_cache_and_index_and_bytecode_at_bcp(Rcache, Rindex, Rtemp, byte_no, 1, index_size);
|
||||
__ cmp(Rtemp, code); // have we resolved this bytecode?
|
||||
@@ -2587,6 +2591,69 @@ void TemplateTable::resolve_cache_and_index(int byte_no,
|
||||
__ bind(resolved);
|
||||
}
|
||||
|
||||
void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
|
||||
Register Rcache,
|
||||
Register Rindex) {
|
||||
assert_different_registers(Rcache, Rindex, Rtemp);
|
||||
|
||||
Label resolved;
|
||||
|
||||
Bytecodes::Code code = bytecode();
|
||||
switch (code) {
|
||||
case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
|
||||
case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
|
||||
__ load_field_entry(Rcache, Rindex);
|
||||
if (byte_no == f1_byte) {
|
||||
__ add(Rtemp, Rcache, in_bytes(ResolvedFieldEntry::get_code_offset()));
|
||||
} else {
|
||||
__ add(Rtemp, Rcache, in_bytes(ResolvedFieldEntry::put_code_offset()));
|
||||
}
|
||||
|
||||
// Load-acquire the bytecode to match store-release in ResolvedFieldEntry::fill_in()
|
||||
__ ldrb(Rtemp, Rtemp);
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), noreg, true);
|
||||
|
||||
__ cmp(Rtemp, code); // have we resolved this bytecode?
|
||||
__ b(resolved, eq);
|
||||
|
||||
// resolve first time through
|
||||
address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
|
||||
__ mov(R1, code);
|
||||
__ call_VM(noreg, entry, R1);
|
||||
// Update registers with resolved info
|
||||
__ load_field_entry(Rcache, Rindex);
|
||||
__ bind(resolved);
|
||||
}
|
||||
|
||||
void TemplateTable::load_resolved_field_entry(Register obj,
|
||||
Register cache,
|
||||
Register tos_state,
|
||||
Register offset,
|
||||
Register flags,
|
||||
bool is_static = false) {
|
||||
assert_different_registers(cache, tos_state, flags, offset);
|
||||
|
||||
// Field offset
|
||||
__ ldr(offset, Address(cache, in_bytes(ResolvedFieldEntry::field_offset_offset())));
|
||||
|
||||
// Flags
|
||||
__ ldrb(flags, Address(cache, in_bytes(ResolvedFieldEntry::flags_offset())));
|
||||
|
||||
// TOS state
|
||||
__ ldrb(tos_state, Address(cache, in_bytes(ResolvedFieldEntry::type_offset())));
|
||||
|
||||
// Klass overwrite register
|
||||
if (is_static) {
|
||||
__ ldr(obj, Address(cache, ResolvedFieldEntry::field_holder_offset()));
|
||||
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
|
||||
__ ldr(obj, Address(obj, mirror_offset));
|
||||
__ resolve_oop_handle(obj);
|
||||
}
|
||||
}
|
||||
|
||||
// The Rcache and Rindex registers must be set before call
|
||||
void TemplateTable::load_field_cp_cache_entry(Register Rcache,
|
||||
@@ -2742,8 +2809,8 @@ void TemplateTable::jvmti_post_field_access(Register Rcache,
|
||||
__ cbz(Rtemp, Lcontinue);
|
||||
|
||||
// cache entry pointer
|
||||
__ add(R2, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord));
|
||||
__ add(R2, R2, in_bytes(ConstantPoolCache::base_offset()));
|
||||
__ load_field_entry(R2, Rindex);
|
||||
|
||||
if (is_static) {
|
||||
__ mov(R1, 0); // null object reference
|
||||
} else {
|
||||
@@ -2756,7 +2823,7 @@ void TemplateTable::jvmti_post_field_access(Register Rcache,
|
||||
// R2: cache entry pointer
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access),
|
||||
R1, R2);
|
||||
__ get_cache_and_index_at_bcp(Rcache, Rindex, 1);
|
||||
__ load_field_entry(Rcache, Rindex);
|
||||
|
||||
__ bind(Lcontinue);
|
||||
}
|
||||
@@ -2773,29 +2840,25 @@ void TemplateTable::pop_and_check_object(Register r) {
|
||||
void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
|
||||
transition(vtos, vtos);
|
||||
|
||||
const Register Roffset = R2_tmp;
|
||||
const Register Robj = R3_tmp;
|
||||
const Register Rcache = R4_tmp;
|
||||
const Register Rflagsav = Rtmp_save0; // R4/R19
|
||||
const Register Rindex = R5_tmp;
|
||||
const Register Rflags = R5_tmp;
|
||||
const Register Rcache = R4_tmp;
|
||||
const Register Rindex = R3_tmp;
|
||||
|
||||
resolve_cache_and_index(byte_no, Rcache, Rindex, sizeof(u2));
|
||||
const Register Roffset = R2_tmp;
|
||||
const Register Rtos_state = R3_tmp;
|
||||
const Register Robj = R4_tmp; // Rcache is free at the time of loading Robj
|
||||
const Register Rflags = R5_tmp;
|
||||
|
||||
resolve_cache_and_index_for_field(byte_no, Rcache, Rindex);
|
||||
jvmti_post_field_access(Rcache, Rindex, is_static, false);
|
||||
load_field_cp_cache_entry(Rcache, Rindex, Roffset, Rflags, Robj, is_static);
|
||||
load_resolved_field_entry(Robj, Rcache, Rtos_state, Roffset, Rflags, is_static);
|
||||
|
||||
__ mov(Rflagsav, Rflags);
|
||||
|
||||
if (!is_static) pop_and_check_object(Robj);
|
||||
if (!is_static) {
|
||||
pop_and_check_object(Robj);
|
||||
}
|
||||
|
||||
Label Done, Lint, Ltable, shouldNotReachHere;
|
||||
Label Lbtos, Lztos, Lctos, Lstos, Litos, Lltos, Lftos, Ldtos, Latos;
|
||||
|
||||
// compute type
|
||||
__ logical_shift_right(Rflags, Rflags, ConstantPoolCacheEntry::tos_state_shift);
|
||||
// Make sure we don't need to mask flags after the above shift
|
||||
ConstantPoolCacheEntry::verify_tos_state_shift();
|
||||
|
||||
// There are actually two versions of implementation of getfield/getstatic:
|
||||
//
|
||||
// 1) Table switch using add(PC,...) instruction (fast_version)
|
||||
@@ -2818,16 +2881,16 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
|
||||
assert(number_of_states == 10, "number of tos states should be equal to 9");
|
||||
|
||||
__ cmp(Rflags, itos);
|
||||
__ cmp(Rtos_state, itos);
|
||||
if(atos_merged_with_itos) {
|
||||
__ cmp(Rflags, atos, ne);
|
||||
__ cmp(Rtos_state, atos, ne);
|
||||
}
|
||||
|
||||
// table switch by type
|
||||
if(fast_version) {
|
||||
__ add(PC, PC, AsmOperand(Rflags, lsl, log_max_block_size + Assembler::LogInstructionSize), ne);
|
||||
__ add(PC, PC, AsmOperand(Rtos_state, lsl, log_max_block_size + Assembler::LogInstructionSize), ne);
|
||||
} else {
|
||||
__ ldr(PC, Address(PC, Rflags, lsl, LogBytesPerWord), ne);
|
||||
__ ldr(PC, Address(PC, Rtos_state, lsl, LogBytesPerWord), ne);
|
||||
}
|
||||
|
||||
// jump to itos/atos case
|
||||
@@ -2868,7 +2931,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
|
||||
// ztos (same as btos for getfield)
|
||||
{
|
||||
assert(ztos == seq++, "btos has unexpected value");
|
||||
assert(ztos == seq++, "ztos has unexpected value");
|
||||
FixedSizeCodeBlock ztos_block(_masm, max_block_size, fast_version);
|
||||
__ bind(Lztos);
|
||||
__ access_load_at(T_BOOLEAN, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg);
|
||||
@@ -2992,13 +3055,13 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
|
||||
__ bind(Done);
|
||||
|
||||
// Check for volatile field
|
||||
Label notVolatile;
|
||||
__ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
|
||||
|
||||
volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp);
|
||||
|
||||
__ bind(notVolatile);
|
||||
{
|
||||
// Check for volatile field
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ResolvedFieldEntry::is_volatile_shift, notVolatile);
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp);
|
||||
__ bind(notVolatile);
|
||||
}
|
||||
}
|
||||
|
||||
void TemplateTable::getfield(int byte_no) {
|
||||
@@ -3029,6 +3092,8 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register Rindex, bool
|
||||
__ ldr_global_s32(Rtemp, (address)JvmtiExport::get_field_modification_count_addr());
|
||||
__ cbz(Rtemp, Lcontinue);
|
||||
|
||||
__ mov(R2, Rcache);
|
||||
|
||||
if (is_static) {
|
||||
// Life is simple. Null out the object pointer.
|
||||
__ mov(R1, 0);
|
||||
@@ -3037,16 +3102,10 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register Rindex, bool
|
||||
// We don't know the size of the value, though; it could be one or two words
|
||||
// depending on its type. As a result, we must find the type to determine where
|
||||
// the object is.
|
||||
__ ldrb(R3, Address(Rcache, in_bytes(ResolvedFieldEntry::type_offset())));
|
||||
|
||||
__ add(Rtemp, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord));
|
||||
__ ldr_u32(Rtemp, Address(Rtemp, cp_base_offset + ConstantPoolCacheEntry::flags_offset()));
|
||||
|
||||
__ logical_shift_right(Rtemp, Rtemp, ConstantPoolCacheEntry::tos_state_shift);
|
||||
// Make sure we don't need to mask Rtemp after the above shift
|
||||
ConstantPoolCacheEntry::verify_tos_state_shift();
|
||||
|
||||
__ cmp(Rtemp, ltos);
|
||||
__ cond_cmp(Rtemp, dtos, ne);
|
||||
__ cmp(R3, ltos);
|
||||
__ cond_cmp(R3, dtos, ne);
|
||||
// two word value (ltos/dtos)
|
||||
__ ldr(R1, Address(SP, Interpreter::expr_offset_in_bytes(2)), eq);
|
||||
|
||||
@@ -3054,10 +3113,6 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register Rindex, bool
|
||||
__ ldr(R1, Address(SP, Interpreter::expr_offset_in_bytes(1)), ne);
|
||||
}
|
||||
|
||||
// cache entry pointer
|
||||
__ add(R2, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord));
|
||||
__ add(R2, R2, in_bytes(cp_base_offset));
|
||||
|
||||
// object (tos)
|
||||
__ mov(R3, Rstack_top);
|
||||
|
||||
@@ -3066,7 +3121,7 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register Rindex, bool
|
||||
// R3: value object on the stack
|
||||
__ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification),
|
||||
R1, R2, R3);
|
||||
__ get_cache_and_index_at_bcp(Rcache, Rindex, 1);
|
||||
__ load_field_entry(Rcache, Rindex);
|
||||
|
||||
__ bind(Lcontinue);
|
||||
}
|
||||
@@ -3076,34 +3131,29 @@ void TemplateTable::jvmti_post_field_mod(Register Rcache, Register Rindex, bool
|
||||
void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
|
||||
transition(vtos, vtos);
|
||||
|
||||
const Register Roffset = R2_tmp;
|
||||
const Register Robj = R3_tmp;
|
||||
const Register Rcache = R4_tmp;
|
||||
const Register Rflagsav = Rtmp_save0; // R4/R19
|
||||
const Register Rindex = R5_tmp;
|
||||
const Register Rflags = R5_tmp;
|
||||
const Register Rcache = R4_tmp;
|
||||
const Register Rindex = R3_tmp;
|
||||
|
||||
resolve_cache_and_index(byte_no, Rcache, Rindex, sizeof(u2));
|
||||
const Register Roffset = R2_tmp;
|
||||
const Register Rtos_state = R3_tmp;
|
||||
const Register Robj = R4_tmp; // Rcache is free at the time of loading Robj
|
||||
const Register Rflags = R5_tmp;
|
||||
|
||||
resolve_cache_and_index_for_field(byte_no, Rcache, Rindex);
|
||||
jvmti_post_field_mod(Rcache, Rindex, is_static);
|
||||
load_field_cp_cache_entry(Rcache, Rindex, Roffset, Rflags, Robj, is_static);
|
||||
load_resolved_field_entry(Robj, Rcache, Rtos_state, Roffset, Rflags, is_static);
|
||||
|
||||
// Check for volatile field
|
||||
Label notVolatile;
|
||||
__ mov(Rflagsav, Rflags);
|
||||
__ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
|
||||
|
||||
volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp);
|
||||
|
||||
__ bind(notVolatile);
|
||||
{
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ResolvedFieldEntry::is_volatile_shift, notVolatile);
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp);
|
||||
__ bind(notVolatile);
|
||||
}
|
||||
|
||||
Label Done, Lint, shouldNotReachHere;
|
||||
Label Ltable, Lbtos, Lztos, Lctos, Lstos, Litos, Lltos, Lftos, Ldtos, Latos;
|
||||
|
||||
// compute type
|
||||
__ logical_shift_right(Rflags, Rflags, ConstantPoolCacheEntry::tos_state_shift);
|
||||
// Make sure we don't need to mask flags after the above shift
|
||||
ConstantPoolCacheEntry::verify_tos_state_shift();
|
||||
|
||||
// There are actually two versions of implementation of putfield/putstatic:
|
||||
//
|
||||
// 32-bit ARM:
|
||||
@@ -3124,13 +3174,13 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
assert(number_of_states == 10, "number of tos states should be equal to 9");
|
||||
|
||||
// itos case is frequent and is moved outside table switch
|
||||
__ cmp(Rflags, itos);
|
||||
__ cmp(Rtos_state, itos);
|
||||
|
||||
// table switch by type
|
||||
if (fast_version) {
|
||||
__ add(PC, PC, AsmOperand(Rflags, lsl, log_max_block_size + Assembler::LogInstructionSize), ne);
|
||||
__ add(PC, PC, AsmOperand(Rtos_state, lsl, log_max_block_size + Assembler::LogInstructionSize), ne);
|
||||
} else {
|
||||
__ ldr(PC, Address(PC, Rflags, lsl, LogBytesPerWord), ne);
|
||||
__ ldr(PC, Address(PC, Rtos_state, lsl, LogBytesPerWord), ne);
|
||||
}
|
||||
|
||||
// jump to itos case
|
||||
@@ -3267,7 +3317,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
|
||||
// atos
|
||||
{
|
||||
assert(atos == seq++, "dtos has unexpected value");
|
||||
assert(atos == seq++, "atos has unexpected value");
|
||||
__ bind(Latos);
|
||||
__ pop(atos);
|
||||
if (!is_static) pop_and_check_object(Robj);
|
||||
@@ -3293,32 +3343,11 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
|
||||
__ bind(Done);
|
||||
|
||||
Label notVolatile2;
|
||||
if (is_static) {
|
||||
// Just check for volatile. Memory barrier for static final field
|
||||
// is handled by class initialization.
|
||||
__ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile2);
|
||||
volatile_barrier(MacroAssembler::StoreLoad, Rtemp);
|
||||
__ bind(notVolatile2);
|
||||
} else {
|
||||
// Check for volatile field and final field
|
||||
Label skipMembar;
|
||||
|
||||
__ tst(Rflagsav, 1 << ConstantPoolCacheEntry::is_volatile_shift |
|
||||
1 << ConstantPoolCacheEntry::is_final_shift);
|
||||
__ b(skipMembar, eq);
|
||||
|
||||
__ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile2);
|
||||
|
||||
// StoreLoad barrier after volatile field write
|
||||
volatile_barrier(MacroAssembler::StoreLoad, Rtemp);
|
||||
__ b(skipMembar);
|
||||
|
||||
// StoreStore barrier after final field write
|
||||
__ bind(notVolatile2);
|
||||
volatile_barrier(MacroAssembler::StoreStore, Rtemp);
|
||||
|
||||
__ bind(skipMembar);
|
||||
{
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ResolvedFieldEntry::is_volatile_shift, notVolatile);
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp);
|
||||
__ bind(notVolatile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3358,7 +3387,7 @@ void TemplateTable::jvmti_post_fast_field_mod(TosState state) {
|
||||
__ push(state); // save value on the stack
|
||||
|
||||
// access constant pool cache entry
|
||||
__ get_cache_entry_pointer_at_bcp(R2, R1, 1);
|
||||
__ load_field_entry(R2, R1);
|
||||
|
||||
__ mov(R1, R3);
|
||||
assert(Interpreter::expr_offset_in_bytes(0) == 0, "adjust this code");
|
||||
@@ -3383,30 +3412,26 @@ void TemplateTable::fast_storefield(TosState state) {
|
||||
|
||||
jvmti_post_fast_field_mod(state);
|
||||
|
||||
const Register Rcache = R2_tmp;
|
||||
const Register Rindex = R3_tmp;
|
||||
const Register Roffset = R3_tmp;
|
||||
const Register Rflags = Rtmp_save0; // R4/R19
|
||||
const Register Robj = R5_tmp;
|
||||
const Register Rcache = R4_tmp;
|
||||
const Register Rindex = R3_tmp;
|
||||
|
||||
const Register Roffset = R2_tmp;
|
||||
const Register Rtos_state = R3_tmp;
|
||||
const Register Robj = R4_tmp; // Rcache is free at the time of loading Robj
|
||||
const Register Rflags = R5_tmp;
|
||||
|
||||
// access constant pool cache
|
||||
__ get_cache_and_index_at_bcp(Rcache, Rindex, 1);
|
||||
|
||||
__ add(Rcache, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord));
|
||||
__ load_field_entry(Rcache, Rindex);
|
||||
load_resolved_field_entry(Robj, Rcache, Rtos_state, Roffset, Rflags);
|
||||
|
||||
// load flags to test volatile
|
||||
__ ldr_u32(Rflags, Address(Rcache, base + ConstantPoolCacheEntry::flags_offset()));
|
||||
|
||||
// replace index with field offset from cache entry
|
||||
__ ldr(Roffset, Address(Rcache, base + ConstantPoolCacheEntry::f2_offset()));
|
||||
|
||||
// Check for volatile store
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
|
||||
|
||||
volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp);
|
||||
|
||||
__ bind(notVolatile);
|
||||
{
|
||||
// Check for volatile store
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ResolvedFieldEntry::is_volatile_shift, notVolatile);
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp);
|
||||
__ bind(notVolatile);
|
||||
}
|
||||
|
||||
// Get object from stack
|
||||
pop_and_check_object(Robj);
|
||||
@@ -3446,23 +3471,14 @@ void TemplateTable::fast_storefield(TosState state) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
Label notVolatile2;
|
||||
Label skipMembar;
|
||||
__ tst(Rflags, 1 << ConstantPoolCacheEntry::is_volatile_shift |
|
||||
1 << ConstantPoolCacheEntry::is_final_shift);
|
||||
__ b(skipMembar, eq);
|
||||
{
|
||||
// Check for volatile store
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ResolvedFieldEntry::is_volatile_shift, notVolatile);
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp);
|
||||
__ bind(notVolatile);
|
||||
}
|
||||
|
||||
__ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile2);
|
||||
|
||||
// StoreLoad barrier after volatile field write
|
||||
volatile_barrier(MacroAssembler::StoreLoad, Rtemp);
|
||||
__ b(skipMembar);
|
||||
|
||||
// StoreStore barrier after final field write
|
||||
__ bind(notVolatile2);
|
||||
volatile_barrier(MacroAssembler::StoreStore, Rtemp);
|
||||
|
||||
__ bind(skipMembar);
|
||||
}
|
||||
|
||||
void TemplateTable::fast_accessfield(TosState state) {
|
||||
@@ -3476,7 +3492,7 @@ void TemplateTable::fast_accessfield(TosState state) {
|
||||
__ ldr_global_s32(R2, (address) JvmtiExport::get_field_access_count_addr());
|
||||
__ cbz(R2, done);
|
||||
// access constant pool cache entry
|
||||
__ get_cache_entry_pointer_at_bcp(R2, R1, 1);
|
||||
__ load_field_entry(R2, R1);
|
||||
__ push_ptr(R0_tos); // save object pointer before call_VM() clobbers it
|
||||
__ verify_oop(R0_tos);
|
||||
__ mov(R1, R0_tos);
|
||||
@@ -3495,16 +3511,15 @@ void TemplateTable::fast_accessfield(TosState state) {
|
||||
const Register Roffset = R3_tmp;
|
||||
|
||||
// access constant pool cache
|
||||
__ get_cache_and_index_at_bcp(Rcache, Rindex, 1);
|
||||
__ load_field_entry(Rcache, Rindex);
|
||||
// replace index with field offset from cache entry
|
||||
__ add(Rtemp, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord));
|
||||
__ ldr(Roffset, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
|
||||
__ ldr(Roffset, Address(Rcache, ResolvedFieldEntry::field_offset_offset()));
|
||||
|
||||
// load flags to test volatile
|
||||
__ ldr_u32(Rflags, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
|
||||
__ ldrb(Rflags, Address(Rcache, ResolvedFieldEntry::flags_offset()));
|
||||
|
||||
__ verify_oop(Robj);
|
||||
__ null_check(Robj, Rtemp);
|
||||
__ null_check(Robj);
|
||||
|
||||
Address addr = Address(Robj, Roffset);
|
||||
// access field
|
||||
@@ -3538,13 +3553,13 @@ void TemplateTable::fast_accessfield(TosState state) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// Check for volatile load
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
|
||||
|
||||
volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp);
|
||||
|
||||
__ bind(notVolatile);
|
||||
{
|
||||
// Check for volatile load
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ResolvedFieldEntry::is_volatile_shift, notVolatile);
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp);
|
||||
__ bind(notVolatile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3562,12 +3577,11 @@ void TemplateTable::fast_xaccess(TosState state) {
|
||||
__ ldr(Robj, aaddress(0));
|
||||
|
||||
// access constant pool cache
|
||||
__ get_cache_and_index_at_bcp(Rcache, Rindex, 2);
|
||||
__ add(Rtemp, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord));
|
||||
__ ldr(Roffset, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
|
||||
__ load_field_entry(Rcache, Rindex, 2);
|
||||
__ ldr(Roffset, Address(Rcache, ResolvedFieldEntry::field_offset_offset()));
|
||||
|
||||
// load flags to test volatile
|
||||
__ ldr_u32(Rflags, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
|
||||
__ ldrb(Rflags, Address(Rcache, ResolvedFieldEntry::flags_offset()));
|
||||
|
||||
// make sure exception is reported in correct bcp range (getfield is next instruction)
|
||||
__ add(Rbcp, Rbcp, 1);
|
||||
@@ -3590,13 +3604,13 @@ void TemplateTable::fast_xaccess(TosState state) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// Check for volatile load
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
|
||||
|
||||
volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp);
|
||||
|
||||
__ bind(notVolatile);
|
||||
{
|
||||
// Check for volatile load
|
||||
Label notVolatile;
|
||||
__ tbz(Rflags, ResolvedFieldEntry::is_volatile_shift, notVolatile);
|
||||
__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp);
|
||||
__ bind(notVolatile);
|
||||
}
|
||||
|
||||
__ bind(done);
|
||||
}
|
||||
|
||||
@@ -71,13 +71,6 @@ void FreezeBase::adjust_interpreted_frame_unextended_sp(frame& f) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
static inline void relativize_one(intptr_t* const vfp, intptr_t* const hfp, int offset) {
|
||||
assert(*(hfp + offset) == *(vfp + offset), "");
|
||||
intptr_t* addr = hfp + offset;
|
||||
intptr_t value = *(intptr_t**)addr - vfp;
|
||||
*addr = value;
|
||||
}
|
||||
|
||||
inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, const frame& hf) {
|
||||
intptr_t* vfp = f.fp();
|
||||
intptr_t* hfp = hf.fp();
|
||||
@@ -90,7 +83,9 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
|
||||
// Make sure that monitors is already relativized.
|
||||
assert(hf.at_absolute(ijava_idx(monitors)) <= -(frame::ijava_state_size / wordSize), "");
|
||||
|
||||
relativize_one(vfp, hfp, ijava_idx(esp));
|
||||
// Make sure that esp is already relativized.
|
||||
assert(hf.at_absolute(ijava_idx(esp)) <= hf.at_absolute(ijava_idx(monitors)), "");
|
||||
|
||||
// top_frame_sp is already relativized
|
||||
|
||||
// hfp == hf.sp() + (f.fp() - f.sp()) is not true on ppc because the stack frame has room for
|
||||
@@ -536,18 +531,15 @@ inline intptr_t* ThawBase::align(const frame& hf, intptr_t* frame_sp, frame& cal
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static inline void derelativize_one(intptr_t* const fp, int offset) {
|
||||
intptr_t* addr = fp + offset;
|
||||
*addr = (intptr_t)(fp + *addr);
|
||||
}
|
||||
|
||||
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
|
||||
intptr_t* vfp = f.fp();
|
||||
|
||||
// Make sure that monitors is still relativized.
|
||||
assert(f.at_absolute(ijava_idx(monitors)) <= -(frame::ijava_state_size / wordSize), "");
|
||||
|
||||
derelativize_one(vfp, ijava_idx(esp));
|
||||
// Make sure that esp is still relativized.
|
||||
assert(f.at_absolute(ijava_idx(esp)) <= f.at_absolute(ijava_idx(monitors)), "");
|
||||
|
||||
// Keep top_frame_sp relativized.
|
||||
}
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ inline oop* frame::interpreter_frame_temp_oop_addr() const {
|
||||
}
|
||||
|
||||
inline intptr_t* frame::interpreter_frame_esp() const {
|
||||
return (intptr_t*) at(ijava_idx(esp));
|
||||
return (intptr_t*) at_relative(ijava_idx(esp));
|
||||
}
|
||||
|
||||
// Convenient setters
|
||||
@@ -235,7 +235,12 @@ inline void frame::interpreter_frame_set_monitor_end(BasicObjectLock* end) {
|
||||
}
|
||||
|
||||
inline void frame::interpreter_frame_set_cpcache(ConstantPoolCache* cp) { *interpreter_frame_cache_addr() = cp; }
|
||||
inline void frame::interpreter_frame_set_esp(intptr_t* esp) { get_ijava_state()->esp = (intptr_t) esp; }
|
||||
|
||||
inline void frame::interpreter_frame_set_esp(intptr_t* esp) {
|
||||
assert(is_interpreted_frame(), "interpreted frame expected");
|
||||
// set relativized esp
|
||||
get_ijava_state()->esp = (intptr_t) (esp - fp());
|
||||
}
|
||||
|
||||
inline void frame::interpreter_frame_set_top_frame_sp(intptr_t* top_frame_sp) {
|
||||
assert(is_interpreted_frame(), "interpreted frame expected");
|
||||
@@ -252,7 +257,7 @@ inline intptr_t* frame::interpreter_frame_expression_stack() const {
|
||||
|
||||
// top of expression stack
|
||||
inline intptr_t* frame::interpreter_frame_tos_address() const {
|
||||
return (intptr_t*)at(ijava_idx(esp)) + Interpreter::stackElementWords;
|
||||
return interpreter_frame_esp() + Interpreter::stackElementWords;
|
||||
}
|
||||
|
||||
inline int frame::interpreter_frame_monitor_size() {
|
||||
|
||||
@@ -2215,7 +2215,9 @@ void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point
|
||||
|
||||
void InterpreterMacroAssembler::save_interpreter_state(Register scratch) {
|
||||
ld(scratch, 0, R1_SP);
|
||||
std(R15_esp, _ijava_state_neg(esp), scratch);
|
||||
subf(R0, scratch, R15_esp);
|
||||
sradi(R0, R0, Interpreter::logStackElementSize);
|
||||
std(R0, _ijava_state_neg(esp), scratch);
|
||||
std(R14_bcp, _ijava_state_neg(bcp), scratch);
|
||||
subf(R0, scratch, R26_monitor);
|
||||
sradi(R0, R0, Interpreter::logStackElementSize);
|
||||
@@ -2245,7 +2247,10 @@ void InterpreterMacroAssembler::restore_interpreter_state(Register scratch, bool
|
||||
ld(R19_method, _ijava_state_neg(method), scratch);
|
||||
ld(R27_constPoolCache, _ijava_state_neg(cpoolCache), scratch);
|
||||
// Following ones are stack addresses and don't require reload.
|
||||
// Derelativize esp
|
||||
ld(R15_esp, _ijava_state_neg(esp), scratch);
|
||||
sldi(R15_esp, R15_esp, Interpreter::logStackElementSize);
|
||||
add(R15_esp, R15_esp, scratch);
|
||||
ld(R18_locals, _ijava_state_neg(locals), scratch);
|
||||
sldi(R18_locals, R18_locals, Interpreter::logStackElementSize);
|
||||
add(R18_locals, R18_locals, scratch);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
#include "runtime/continuation.hpp"
|
||||
#include "runtime/continuationEntry.inline.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
@@ -4717,6 +4718,20 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
#endif // INCLUDE_JFR
|
||||
|
||||
// exception handler for upcall stubs
|
||||
address generate_upcall_stub_exception_handler() {
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
|
||||
address start = __ pc();
|
||||
|
||||
// Native caller has no idea how to handle exceptions,
|
||||
// so we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(R3_ARG1);
|
||||
__ load_const_optimized(R12_scratch2, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception), R0);
|
||||
__ call_c(R12_scratch2);
|
||||
__ should_not_reach_here();
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Initialization
|
||||
void generate_initial_stubs() {
|
||||
@@ -4796,6 +4811,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
// arraycopy stubs used by compilers
|
||||
generate_arraycopy_stubs();
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
}
|
||||
|
||||
void generate_compiler_stubs() {
|
||||
|
||||
@@ -1059,7 +1059,9 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
|
||||
__ std(R12_scratch2, _ijava_state_neg(monitors), R1_SP);
|
||||
__ std(R14_bcp, _ijava_state_neg(bcp), R1_SP);
|
||||
if (ProfileInterpreter) { __ std(R28_mdx, _ijava_state_neg(mdx), R1_SP); }
|
||||
__ std(R15_esp, _ijava_state_neg(esp), R1_SP);
|
||||
__ sub(R12_scratch2, R15_esp, R1_SP);
|
||||
__ sradi(R12_scratch2, R12_scratch2, Interpreter::logStackElementSize);
|
||||
__ std(R12_scratch2, _ijava_state_neg(esp), R1_SP);
|
||||
__ std(R0, _ijava_state_neg(oop_tmp), R1_SP); // only used for native_call
|
||||
|
||||
// Store sender's SP and this frame's top SP.
|
||||
|
||||
@@ -115,7 +115,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
__ block_comment("} restore_callee_saved_regs ");
|
||||
}
|
||||
|
||||
static const int upcall_stub_code_base_size = 1536; // depends on GC (resolve_jobject)
|
||||
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,
|
||||
@@ -217,6 +217,7 @@ 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");
|
||||
@@ -232,8 +233,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
__ block_comment("{ receiver ");
|
||||
__ load_const_optimized(R3_ARG1, (intptr_t)receiver, R0);
|
||||
__ resolve_jobject(R3_ARG1, tmp, R31, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS); // kills R31
|
||||
__ get_vm_result(R3_ARG1);
|
||||
__ block_comment("} receiver ");
|
||||
|
||||
__ load_const_optimized(R19_method, (intptr_t)entry);
|
||||
@@ -314,19 +314,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__ block_comment("{ exception handler");
|
||||
|
||||
intptr_t exception_handler_offset = __ pc() - start;
|
||||
|
||||
// Native caller has no idea how to handle exceptions,
|
||||
// so we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(R3_ARG1);
|
||||
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception), R0);
|
||||
__ call_c(call_target_address);
|
||||
__ should_not_reach_here();
|
||||
|
||||
__ block_comment("} exception handler");
|
||||
|
||||
_masm->flush();
|
||||
|
||||
#ifndef PRODUCT
|
||||
@@ -342,7 +329,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
UpcallStub* blob
|
||||
= UpcallStub::create(name,
|
||||
&buffer,
|
||||
exception_handler_offset,
|
||||
receiver,
|
||||
in_ByteSize(frame_data_offset));
|
||||
#ifndef ABI_ELFv2
|
||||
|
||||
@@ -1074,7 +1074,26 @@ enum operand_size { int8, int16, int32, uint32, int64 };
|
||||
|
||||
#undef INSN
|
||||
|
||||
// Float and Double Conversion Instruction
|
||||
enum fclass_mask {
|
||||
minf = 1 << 0, // negative infinite
|
||||
mnorm = 1 << 1, // negative normal number
|
||||
msubnorm = 1 << 2, // negative subnormal number
|
||||
mzero = 1 << 3, // negative zero
|
||||
pzero = 1 << 4, // positive zero
|
||||
psubnorm = 1 << 5, // positive subnormal number
|
||||
pnorm = 1 << 6, // positive normal number
|
||||
pinf = 1 << 7, // positive infinite
|
||||
snan = 1 << 8, // signaling NaN
|
||||
qnan = 1 << 9, // quiet NaN
|
||||
zero = mzero | pzero,
|
||||
subnorm = msubnorm | psubnorm,
|
||||
norm = mnorm | pnorm,
|
||||
inf = minf | pinf,
|
||||
nan = snan | qnan,
|
||||
finite = zero | subnorm | norm,
|
||||
};
|
||||
|
||||
// Float and Double Conversion/Classify Instruction
|
||||
#define INSN(NAME, op, funct3, funct5, funct7) \
|
||||
void NAME(Register Rd, FloatRegister Rs1) { \
|
||||
unsigned insn = 0; \
|
||||
@@ -1790,6 +1809,11 @@ enum Nf {
|
||||
INSN(vlse32_v, 0b0000111, 0b110, 0b10, 0b0);
|
||||
INSN(vlse64_v, 0b0000111, 0b111, 0b10, 0b0);
|
||||
|
||||
INSN(vsse8_v, 0b0100111, 0b000, 0b10, 0b0);
|
||||
INSN(vsse16_v, 0b0100111, 0b101, 0b10, 0b0);
|
||||
INSN(vsse32_v, 0b0100111, 0b110, 0b10, 0b0);
|
||||
INSN(vsse64_v, 0b0100111, 0b111, 0b10, 0b0);
|
||||
|
||||
#undef INSN
|
||||
#undef patch_VLdSt
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right,
|
||||
}
|
||||
} else {
|
||||
Register rreg = right->as_register();
|
||||
__ corrected_idivl(dreg, lreg, rreg, is_irem);
|
||||
__ corrected_idivl(dreg, lreg, rreg, is_irem, /* is_signed */ true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,8 +172,12 @@ void LIR_Assembler::arith_op_double_cpu(LIR_Code code, LIR_Opr left, LIR_Opr rig
|
||||
case lir_add: __ add(dest->as_register_lo(), lreg_lo, rreg_lo); break;
|
||||
case lir_sub: __ sub(dest->as_register_lo(), lreg_lo, rreg_lo); break;
|
||||
case lir_mul: __ mul(dest->as_register_lo(), lreg_lo, rreg_lo); break;
|
||||
case lir_div: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo, false); break;
|
||||
case lir_rem: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo, true); break;
|
||||
case lir_div: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo,
|
||||
/* want_remainder */ false, /* is_signed */ true);
|
||||
break;
|
||||
case lir_rem: __ corrected_idivq(dest->as_register_lo(), lreg_lo, rreg_lo,
|
||||
/* want_remainder */ true, /* is_signed */ true);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
@@ -1515,7 +1515,7 @@ void LIR_Assembler::emit_lock(LIR_OpLock* op) {
|
||||
if (LockingMode == LM_MONITOR) {
|
||||
if (op->info() != nullptr) {
|
||||
add_debug_info_for_null_check_here(op->info());
|
||||
__ null_check(obj);
|
||||
__ null_check(obj, -1);
|
||||
}
|
||||
__ j(*op->stub()->entry());
|
||||
} else if (op->code() == lir_lock) {
|
||||
|
||||
@@ -801,7 +801,7 @@ void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
|
||||
}
|
||||
|
||||
void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
|
||||
fatal("vectorizedMismatch intrinsic is not implemented on this platform");
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f
|
||||
|
||||
@@ -63,7 +63,7 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(flag, oop);
|
||||
lwu(flag, Address(flag, Klass::access_flags_offset()));
|
||||
test_bit(flag, flag, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS), tmp /* tmp */);
|
||||
test_bit(flag, flag, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
|
||||
bnez(flag, cont, true /* is_far */);
|
||||
}
|
||||
|
||||
@@ -1571,7 +1571,7 @@ void C2_MacroAssembler::minmax_fp(FloatRegister dst, FloatRegister src1, FloatRe
|
||||
is_double ? fclass_d(t1, src2)
|
||||
: fclass_s(t1, src2);
|
||||
orr(t0, t0, t1);
|
||||
andi(t0, t0, 0b1100000000); //if src1 or src2 is quiet or signaling NaN then return NaN
|
||||
andi(t0, t0, fclass_mask::nan); // if src1 or src2 is quiet or signaling NaN then return NaN
|
||||
beqz(t0, Compare);
|
||||
is_double ? fadd_d(dst, src1, src2)
|
||||
: fadd_s(dst, src1, src2);
|
||||
@@ -1653,6 +1653,34 @@ void C2_MacroAssembler::round_double_mode(FloatRegister dst, FloatRegister src,
|
||||
bind(done);
|
||||
}
|
||||
|
||||
// According to Java SE specification, for floating-point signum operations, if
|
||||
// on input we have NaN or +/-0.0 value we should return it,
|
||||
// otherwise return +/- 1.0 using sign of input.
|
||||
// one - gives us a floating-point 1.0 (got from matching rule)
|
||||
// bool is_double - specifies single or double precision operations will be used.
|
||||
void C2_MacroAssembler::signum_fp(FloatRegister dst, FloatRegister src, FloatRegister one, bool is_double) {
|
||||
Register tmp1 = t0;
|
||||
|
||||
Label done;
|
||||
|
||||
is_double ? fclass_d(tmp1, src)
|
||||
: fclass_s(tmp1, src);
|
||||
|
||||
is_double ? fmv_d(dst, src)
|
||||
: fmv_s(dst, src);
|
||||
|
||||
// check if input is -0, +0, signaling NaN or quiet NaN
|
||||
andi(tmp1, tmp1, fclass_mask::zero | fclass_mask::nan);
|
||||
|
||||
bnez(tmp1, done);
|
||||
|
||||
// use floating-point 1.0 with a sign of input
|
||||
is_double ? fsgnj_d(dst, one, src)
|
||||
: fsgnj_s(dst, one, src);
|
||||
|
||||
bind(done);
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::element_compare(Register a1, Register a2, Register result, Register cnt, Register tmp1, Register tmp2,
|
||||
VectorRegister vr1, VectorRegister vr2, VectorRegister vrs, bool islatin, Label &DONE) {
|
||||
Label loop;
|
||||
|
||||
@@ -157,6 +157,9 @@
|
||||
void round_double_mode(FloatRegister dst, FloatRegister src, int round_mode,
|
||||
Register tmp1, Register tmp2, Register tmp3);
|
||||
|
||||
void signum_fp(FloatRegister dst, FloatRegister src, FloatRegister one,
|
||||
bool is_double);
|
||||
|
||||
// intrinsic methods implemented by rvv instructions
|
||||
void string_equals_v(Register r1, Register r2,
|
||||
Register result, Register cnt1,
|
||||
|
||||
@@ -2386,7 +2386,7 @@ void MacroAssembler::store_heap_oop_null(Address dst) {
|
||||
}
|
||||
|
||||
int MacroAssembler::corrected_idivl(Register result, Register rs1, Register rs2,
|
||||
bool want_remainder)
|
||||
bool want_remainder, bool is_signed)
|
||||
{
|
||||
// Full implementation of Java idiv and irem. The function
|
||||
// returns the (pc) offset of the div instruction - may be needed
|
||||
@@ -2402,15 +2402,24 @@ int MacroAssembler::corrected_idivl(Register result, Register rs1, Register rs2,
|
||||
|
||||
int idivl_offset = offset();
|
||||
if (!want_remainder) {
|
||||
divw(result, rs1, rs2);
|
||||
if (is_signed) {
|
||||
divw(result, rs1, rs2);
|
||||
} else {
|
||||
divuw(result, rs1, rs2);
|
||||
}
|
||||
} else {
|
||||
remw(result, rs1, rs2); // result = rs1 % rs2;
|
||||
// result = rs1 % rs2;
|
||||
if (is_signed) {
|
||||
remw(result, rs1, rs2);
|
||||
} else {
|
||||
remuw(result, rs1, rs2);
|
||||
}
|
||||
}
|
||||
return idivl_offset;
|
||||
}
|
||||
|
||||
int MacroAssembler::corrected_idivq(Register result, Register rs1, Register rs2,
|
||||
bool want_remainder)
|
||||
bool want_remainder, bool is_signed)
|
||||
{
|
||||
// Full implementation of Java ldiv and lrem. The function
|
||||
// returns the (pc) offset of the div instruction - may be needed
|
||||
@@ -2425,9 +2434,18 @@ int MacroAssembler::corrected_idivq(Register result, Register rs1, Register rs2,
|
||||
|
||||
int idivq_offset = offset();
|
||||
if (!want_remainder) {
|
||||
div(result, rs1, rs2);
|
||||
if (is_signed) {
|
||||
div(result, rs1, rs2);
|
||||
} else {
|
||||
divu(result, rs1, rs2);
|
||||
}
|
||||
} else {
|
||||
rem(result, rs1, rs2); // result = rs1 % rs2;
|
||||
// result = rs1 % rs2;
|
||||
if (is_signed) {
|
||||
rem(result, rs1, rs2);
|
||||
} else {
|
||||
remu(result, rs1, rs2);
|
||||
}
|
||||
}
|
||||
return idivq_offset;
|
||||
}
|
||||
@@ -4228,7 +4246,7 @@ void MacroAssembler::FLOATCVT##_safe(Register dst, FloatRegister src, Register t
|
||||
fclass_##FLOATSIG(tmp, src); \
|
||||
mv(dst, zr); \
|
||||
/* check if src is NaN */ \
|
||||
andi(tmp, tmp, 0b1100000000); \
|
||||
andi(tmp, tmp, fclass_mask::nan); \
|
||||
bnez(tmp, done); \
|
||||
FLOATCVT(dst, src); \
|
||||
bind(done); \
|
||||
@@ -4404,8 +4422,8 @@ void MacroAssembler::sign_extend(Register dst, Register src, int bits) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_l2i(Register dst, Register src1, Register src2, Register tmp)
|
||||
{
|
||||
void MacroAssembler::cmp_x2i(Register dst, Register src1, Register src2,
|
||||
Register tmp, bool is_signed) {
|
||||
if (src1 == src2) {
|
||||
mv(dst, zr);
|
||||
return;
|
||||
@@ -4424,14 +4442,35 @@ void MacroAssembler::cmp_l2i(Register dst, Register src1, Register src2, Registe
|
||||
}
|
||||
|
||||
// installs 1 if gt else 0
|
||||
slt(dst, right, left);
|
||||
if (is_signed) {
|
||||
slt(dst, right, left);
|
||||
} else {
|
||||
sltu(dst, right, left);
|
||||
}
|
||||
bnez(dst, done);
|
||||
slt(dst, left, right);
|
||||
if (is_signed) {
|
||||
slt(dst, left, right);
|
||||
} else {
|
||||
sltu(dst, left, right);
|
||||
}
|
||||
// dst = -1 if lt; else if eq , dst = 0
|
||||
neg(dst, dst);
|
||||
bind(done);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_l2i(Register dst, Register src1, Register src2, Register tmp)
|
||||
{
|
||||
cmp_x2i(dst, src1, src2, tmp);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_ul2i(Register dst, Register src1, Register src2, Register tmp) {
|
||||
cmp_x2i(dst, src1, src2, tmp, false);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_uw2i(Register dst, Register src1, Register src2, Register tmp) {
|
||||
cmp_x2i(dst, src1, src2, tmp, false);
|
||||
}
|
||||
|
||||
// The java_calling_convention describes stack locations as ideal slots on
|
||||
// a frame with no abi restrictions. Since we must observe abi restrictions
|
||||
// (like the placement of the register window) the slots must be biased by
|
||||
@@ -4638,13 +4677,19 @@ void MacroAssembler::rt_call(address dest, Register tmp) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos, Register tmp) {
|
||||
void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos) {
|
||||
assert(bit_pos < 64, "invalid bit range");
|
||||
if (UseZbs) {
|
||||
bexti(Rd, Rs, bit_pos);
|
||||
return;
|
||||
}
|
||||
andi(Rd, Rs, 1UL << bit_pos, tmp);
|
||||
int64_t imm = (int64_t)(1UL << bit_pos);
|
||||
if (is_simm12(imm)) {
|
||||
and_imm12(Rd, Rs, imm);
|
||||
} else {
|
||||
srli(Rd, Rs, bit_pos);
|
||||
and_imm12(Rd, Rd, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Implements lightweight-locking.
|
||||
|
||||
@@ -241,9 +241,9 @@ class MacroAssembler: public Assembler {
|
||||
|
||||
// idiv variant which deals with MINLONG as dividend and -1 as divisor
|
||||
int corrected_idivl(Register result, Register rs1, Register rs2,
|
||||
bool want_remainder);
|
||||
bool want_remainder, bool is_signed);
|
||||
int corrected_idivq(Register result, Register rs1, Register rs2,
|
||||
bool want_remainder);
|
||||
bool want_remainder, bool is_signed);
|
||||
|
||||
// interface method calling
|
||||
void lookup_interface_method(Register recv_klass,
|
||||
@@ -1240,7 +1240,7 @@ public:
|
||||
void shadd(Register Rd, Register Rs1, Register Rs2, Register tmp, int shamt);
|
||||
|
||||
// test single bit in Rs, result is set to Rd
|
||||
void test_bit(Register Rd, Register Rs, uint32_t bit_pos, Register tmp = t0);
|
||||
void test_bit(Register Rd, Register Rs, uint32_t bit_pos);
|
||||
|
||||
// Here the float instructions with safe deal with some exceptions.
|
||||
// e.g. convert from NaN, +Inf, -Inf to int, float, double
|
||||
@@ -1289,6 +1289,13 @@ public:
|
||||
}
|
||||
|
||||
// vector pseudo instructions
|
||||
// rotate vector register left with shift bits, 32-bit version
|
||||
inline void vrole32_vi(VectorRegister vd, uint32_t shift, VectorRegister tmp_vr) {
|
||||
vsrl_vi(tmp_vr, vd, 32 - shift);
|
||||
vsll_vi(vd, vd, shift);
|
||||
vor_vv(vd, vd, tmp_vr);
|
||||
}
|
||||
|
||||
inline void vl1r_v(VectorRegister vd, Register rs) {
|
||||
vl1re8_v(vd, rs);
|
||||
}
|
||||
@@ -1387,11 +1394,17 @@ public:
|
||||
void zero_extend(Register dst, Register src, int bits);
|
||||
void sign_extend(Register dst, Register src, int bits);
|
||||
|
||||
private:
|
||||
void cmp_x2i(Register dst, Register src1, Register src2, Register tmp, bool is_signed = true);
|
||||
|
||||
public:
|
||||
// compare src1 and src2 and get -1/0/1 in dst.
|
||||
// if [src1 > src2], dst = 1;
|
||||
// if [src1 == src2], dst = 0;
|
||||
// if [src1 < src2], dst = -1;
|
||||
void cmp_l2i(Register dst, Register src1, Register src2, Register tmp = t0);
|
||||
void cmp_ul2i(Register dst, Register src1, Register src2, Register tmp = t0);
|
||||
void cmp_uw2i(Register dst, Register src1, Register src2, Register tmp = t0);
|
||||
|
||||
// support for argument shuffling
|
||||
void move32_64(VMRegPair src, VMRegPair dst, Register tmp = t0);
|
||||
|
||||
@@ -983,8 +983,8 @@ definitions %{
|
||||
int_def XFER_COST ( 300, 3 * DEFAULT_COST); // mfc, mtc, fcvt, fmove, fcmp
|
||||
int_def BRANCH_COST ( 200, 2 * DEFAULT_COST); // branch, jmp, call
|
||||
int_def IMUL_COST ( 1000, 10 * DEFAULT_COST); // imul
|
||||
int_def IDIVSI_COST ( 3400, 34 * DEFAULT_COST); // idivdi
|
||||
int_def IDIVDI_COST ( 6600, 66 * DEFAULT_COST); // idivsi
|
||||
int_def IDIVSI_COST ( 3400, 34 * DEFAULT_COST); // idivsi
|
||||
int_def IDIVDI_COST ( 6600, 66 * DEFAULT_COST); // idivdi
|
||||
int_def FMUL_SINGLE_COST ( 500, 5 * DEFAULT_COST); // fmul, fmadd
|
||||
int_def FMUL_DOUBLE_COST ( 700, 7 * DEFAULT_COST); // fmul, fmadd
|
||||
int_def FDIV_COST ( 2000, 20 * DEFAULT_COST); // fdiv
|
||||
@@ -2443,7 +2443,15 @@ encode %{
|
||||
Register dst_reg = as_Register($dst$$reg);
|
||||
Register src1_reg = as_Register($src1$$reg);
|
||||
Register src2_reg = as_Register($src2$$reg);
|
||||
__ corrected_idivl(dst_reg, src1_reg, src2_reg, false);
|
||||
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true);
|
||||
%}
|
||||
|
||||
enc_class riscv_enc_divuw(iRegI dst, iRegI src1, iRegI src2) %{
|
||||
C2_MacroAssembler _masm(&cbuf);
|
||||
Register dst_reg = as_Register($dst$$reg);
|
||||
Register src1_reg = as_Register($src1$$reg);
|
||||
Register src2_reg = as_Register($src2$$reg);
|
||||
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false);
|
||||
%}
|
||||
|
||||
enc_class riscv_enc_div(iRegI dst, iRegI src1, iRegI src2) %{
|
||||
@@ -2451,7 +2459,15 @@ encode %{
|
||||
Register dst_reg = as_Register($dst$$reg);
|
||||
Register src1_reg = as_Register($src1$$reg);
|
||||
Register src2_reg = as_Register($src2$$reg);
|
||||
__ corrected_idivq(dst_reg, src1_reg, src2_reg, false);
|
||||
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ true);
|
||||
%}
|
||||
|
||||
enc_class riscv_enc_divu(iRegI dst, iRegI src1, iRegI src2) %{
|
||||
C2_MacroAssembler _masm(&cbuf);
|
||||
Register dst_reg = as_Register($dst$$reg);
|
||||
Register src1_reg = as_Register($src1$$reg);
|
||||
Register src2_reg = as_Register($src2$$reg);
|
||||
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ false, /* is_signed */ false);
|
||||
%}
|
||||
|
||||
enc_class riscv_enc_modw(iRegI dst, iRegI src1, iRegI src2) %{
|
||||
@@ -2459,7 +2475,15 @@ encode %{
|
||||
Register dst_reg = as_Register($dst$$reg);
|
||||
Register src1_reg = as_Register($src1$$reg);
|
||||
Register src2_reg = as_Register($src2$$reg);
|
||||
__ corrected_idivl(dst_reg, src1_reg, src2_reg, true);
|
||||
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true);
|
||||
%}
|
||||
|
||||
enc_class riscv_enc_moduw(iRegI dst, iRegI src1, iRegI src2) %{
|
||||
C2_MacroAssembler _masm(&cbuf);
|
||||
Register dst_reg = as_Register($dst$$reg);
|
||||
Register src1_reg = as_Register($src1$$reg);
|
||||
Register src2_reg = as_Register($src2$$reg);
|
||||
__ corrected_idivl(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ false);
|
||||
%}
|
||||
|
||||
enc_class riscv_enc_mod(iRegI dst, iRegI src1, iRegI src2) %{
|
||||
@@ -2467,7 +2491,15 @@ encode %{
|
||||
Register dst_reg = as_Register($dst$$reg);
|
||||
Register src1_reg = as_Register($src1$$reg);
|
||||
Register src2_reg = as_Register($src2$$reg);
|
||||
__ corrected_idivq(dst_reg, src1_reg, src2_reg, true);
|
||||
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ true);
|
||||
%}
|
||||
|
||||
enc_class riscv_enc_modu(iRegI dst, iRegI src1, iRegI src2) %{
|
||||
C2_MacroAssembler _masm(&cbuf);
|
||||
Register dst_reg = as_Register($dst$$reg);
|
||||
Register src1_reg = as_Register($src1$$reg);
|
||||
Register src2_reg = as_Register($src2$$reg);
|
||||
__ corrected_idivq(dst_reg, src1_reg, src2_reg, /* want_remainder */ true, /* is_signed */ false);
|
||||
%}
|
||||
|
||||
enc_class riscv_enc_tail_call(iRegP jump_target) %{
|
||||
@@ -6673,6 +6705,15 @@ instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
|
||||
ins_pipe(idiv_reg_reg);
|
||||
%}
|
||||
|
||||
instruct UdivI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
|
||||
match(Set dst (UDivI src1 src2));
|
||||
ins_cost(IDIVSI_COST);
|
||||
format %{ "divuw $dst, $src1, $src2\t#@UdivI"%}
|
||||
|
||||
ins_encode(riscv_enc_divuw(dst, src1, src2));
|
||||
ins_pipe(idiv_reg_reg);
|
||||
%}
|
||||
|
||||
instruct signExtract(iRegINoSp dst, iRegIorL2I src1, immI_31 div1, immI_31 div2) %{
|
||||
match(Set dst (URShiftI (RShiftI src1 div1) div2));
|
||||
ins_cost(ALU_COST);
|
||||
@@ -6695,6 +6736,16 @@ instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
|
||||
ins_pipe(ldiv_reg_reg);
|
||||
%}
|
||||
|
||||
instruct UdivL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
|
||||
match(Set dst (UDivL src1 src2));
|
||||
ins_cost(IDIVDI_COST);
|
||||
|
||||
format %{ "divu $dst, $src1, $src2\t#@UdivL" %}
|
||||
|
||||
ins_encode(riscv_enc_divu(dst, src1, src2));
|
||||
ins_pipe(ldiv_reg_reg);
|
||||
%}
|
||||
|
||||
instruct signExtractL(iRegLNoSp dst, iRegL src1, immI_63 div1, immI_63 div2) %{
|
||||
match(Set dst (URShiftL (RShiftL src1 div1) div2));
|
||||
ins_cost(ALU_COST);
|
||||
@@ -6717,6 +6768,15 @@ instruct modI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct UmodI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{
|
||||
match(Set dst (UModI src1 src2));
|
||||
ins_cost(IDIVSI_COST);
|
||||
format %{ "remuw $dst, $src1, $src2\t#@UmodI" %}
|
||||
|
||||
ins_encode(riscv_enc_moduw(dst, src1, src2));
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
// Long Remainder
|
||||
|
||||
instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
|
||||
@@ -6728,6 +6788,15 @@ instruct modL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
instruct UmodL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
|
||||
match(Set dst (UModL src1 src2));
|
||||
ins_cost(IDIVDI_COST);
|
||||
format %{ "remu $dst, $src1, $src2\t#@UmodL" %}
|
||||
|
||||
ins_encode(riscv_enc_modu(dst, src1, src2));
|
||||
ins_pipe(ialu_reg_reg);
|
||||
%}
|
||||
|
||||
// Integer Shifts
|
||||
|
||||
// Shift Left Register
|
||||
@@ -7292,7 +7361,7 @@ instruct isInfiniteF_reg_reg(iRegINoSp dst, fRegF src)
|
||||
format %{ "isInfinite $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg));
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), 0b0010000001);
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::inf);
|
||||
__ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
|
||||
%}
|
||||
|
||||
@@ -7307,7 +7376,7 @@ instruct isInfiniteD_reg_reg(iRegINoSp dst, fRegD src)
|
||||
format %{ "isInfinite $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg));
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), 0b0010000001);
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::inf);
|
||||
__ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
|
||||
%}
|
||||
|
||||
@@ -7322,7 +7391,7 @@ instruct isFiniteF_reg_reg(iRegINoSp dst, fRegF src)
|
||||
format %{ "isFinite $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ fclass_s(as_Register($dst$$reg), as_FloatRegister($src$$reg));
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), 0b0001111110);
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::finite);
|
||||
__ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
|
||||
%}
|
||||
|
||||
@@ -7337,7 +7406,7 @@ instruct isFiniteD_reg_reg(iRegINoSp dst, fRegD src)
|
||||
format %{ "isFinite $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ fclass_d(as_Register($dst$$reg), as_FloatRegister($src$$reg));
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), 0b0001111110);
|
||||
__ andi(as_Register($dst$$reg), as_Register($dst$$reg), Assembler::fclass_mask::finite);
|
||||
__ slt(as_Register($dst$$reg), zr, as_Register($dst$$reg));
|
||||
%}
|
||||
|
||||
@@ -7506,6 +7575,52 @@ instruct roundD_reg(fRegD dst, fRegD src, immI rmode, iRegLNoSp tmp1, iRegLNoSp
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// Copysign and signum intrinsics
|
||||
|
||||
instruct copySignD_reg(fRegD dst, fRegD src1, fRegD src2, immD zero) %{
|
||||
match(Set dst (CopySignD src1 (Binary src2 zero)));
|
||||
format %{ "CopySignD $dst $src1 $src2" %}
|
||||
ins_encode %{
|
||||
FloatRegister dst = as_FloatRegister($dst$$reg),
|
||||
src1 = as_FloatRegister($src1$$reg),
|
||||
src2 = as_FloatRegister($src2$$reg);
|
||||
__ fsgnj_d(dst, src1, src2);
|
||||
%}
|
||||
ins_pipe(fp_dop_reg_reg_d);
|
||||
%}
|
||||
|
||||
instruct copySignF_reg(fRegF dst, fRegF src1, fRegF src2) %{
|
||||
match(Set dst (CopySignF src1 src2));
|
||||
format %{ "CopySignF $dst $src1 $src2" %}
|
||||
ins_encode %{
|
||||
FloatRegister dst = as_FloatRegister($dst$$reg),
|
||||
src1 = as_FloatRegister($src1$$reg),
|
||||
src2 = as_FloatRegister($src2$$reg);
|
||||
__ fsgnj_s(dst, src1, src2);
|
||||
%}
|
||||
ins_pipe(fp_dop_reg_reg_s);
|
||||
%}
|
||||
|
||||
instruct signumD_reg(fRegD dst, fRegD src, immD zero, fRegD one) %{
|
||||
match(Set dst (SignumD src (Binary zero one)));
|
||||
format %{ "signumD $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ signum_fp(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($one$$reg), true /* is_double */);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct signumF_reg(fRegF dst, fRegF src, immF zero, fRegF one) %{
|
||||
match(Set dst (SignumF src (Binary zero one)));
|
||||
format %{ "signumF $dst, $src" %}
|
||||
ins_encode %{
|
||||
__ signum_fp(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg),
|
||||
as_FloatRegister($one$$reg), false /* is_double */);
|
||||
%}
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// Arithmetic Instructions End
|
||||
|
||||
// ============================================================================
|
||||
@@ -8595,6 +8710,42 @@ instruct cmpL3_reg_reg(iRegINoSp dst, iRegL op1, iRegL op2)
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct cmpUL3_reg_reg(iRegINoSp dst, iRegL op1, iRegL op2)
|
||||
%{
|
||||
match(Set dst (CmpUL3 op1 op2));
|
||||
|
||||
ins_cost(ALU_COST * 3 + BRANCH_COST);
|
||||
format %{ "sltu $dst, $op2, $op1\t#@cmpUL3_reg_reg\n\t"
|
||||
"bnez $dst, done\n\t"
|
||||
"sltu $dst, $op1, $op2\n\t"
|
||||
"neg $dst, $dst\t#@cmpUL3_reg_reg"
|
||||
%}
|
||||
ins_encode %{
|
||||
__ cmp_ul2i(t0, as_Register($op1$$reg), as_Register($op2$$reg));
|
||||
__ mv(as_Register($dst$$reg), t0);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct cmpU3_reg_reg(iRegINoSp dst, iRegI op1, iRegI op2)
|
||||
%{
|
||||
match(Set dst (CmpU3 op1 op2));
|
||||
|
||||
ins_cost(ALU_COST * 3 + BRANCH_COST);
|
||||
format %{ "sltu $dst, $op2, $op1\t#@cmpU3_reg_reg\n\t"
|
||||
"bnez $dst, done\n\t"
|
||||
"sltu $dst, $op1, $op2\n\t"
|
||||
"neg $dst, $dst\t#@cmpU3_reg_reg"
|
||||
%}
|
||||
ins_encode %{
|
||||
__ cmp_uw2i(t0, as_Register($op1$$reg), as_Register($op2$$reg));
|
||||
__ mv(as_Register($dst$$reg), t0);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
instruct cmpLTMask_reg_reg(iRegINoSp dst, iRegI p, iRegI q)
|
||||
%{
|
||||
match(Set dst (CmpLTMask p q));
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
#include "runtime/continuation.hpp"
|
||||
#include "runtime/continuationEntry.inline.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
@@ -4277,6 +4278,142 @@ class StubGenerator: public StubCodeGenerator {
|
||||
return (address) start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the quarter round calculations on values contained within four vector registers.
|
||||
*
|
||||
* @param aVec the SIMD register containing only the "a" values
|
||||
* @param bVec the SIMD register containing only the "b" values
|
||||
* @param cVec the SIMD register containing only the "c" values
|
||||
* @param dVec the SIMD register containing only the "d" values
|
||||
* @param tmp_vr temporary vector register holds intermedia values.
|
||||
*/
|
||||
void chacha20_quarter_round(VectorRegister aVec, VectorRegister bVec,
|
||||
VectorRegister cVec, VectorRegister dVec, VectorRegister tmp_vr) {
|
||||
// a += b, d ^= a, d <<<= 16
|
||||
__ vadd_vv(aVec, aVec, bVec);
|
||||
__ vxor_vv(dVec, dVec, aVec);
|
||||
__ vrole32_vi(dVec, 16, tmp_vr);
|
||||
|
||||
// c += d, b ^= c, b <<<= 12
|
||||
__ vadd_vv(cVec, cVec, dVec);
|
||||
__ vxor_vv(bVec, bVec, cVec);
|
||||
__ vrole32_vi(bVec, 12, tmp_vr);
|
||||
|
||||
// a += b, d ^= a, d <<<= 8
|
||||
__ vadd_vv(aVec, aVec, bVec);
|
||||
__ vxor_vv(dVec, dVec, aVec);
|
||||
__ vrole32_vi(dVec, 8, tmp_vr);
|
||||
|
||||
// c += d, b ^= c, b <<<= 7
|
||||
__ vadd_vv(cVec, cVec, dVec);
|
||||
__ vxor_vv(bVec, bVec, cVec);
|
||||
__ vrole32_vi(bVec, 7, tmp_vr);
|
||||
}
|
||||
|
||||
/**
|
||||
* int com.sun.crypto.provider.ChaCha20Cipher.implChaCha20Block(int[] initState, byte[] result)
|
||||
*
|
||||
* Input arguments:
|
||||
* c_rarg0 - state, the starting state
|
||||
* c_rarg1 - key_stream, the array that will hold the result of the ChaCha20 block function
|
||||
*
|
||||
* Implementation Note:
|
||||
* Parallelization is achieved by loading individual state elements into vectors for N blocks.
|
||||
* N depends on single vector register length.
|
||||
*/
|
||||
address generate_chacha20Block() {
|
||||
Label L_Rounds;
|
||||
|
||||
__ align(CodeEntryAlignment);
|
||||
StubCodeMark mark(this, "StubRoutines", "chacha20Block");
|
||||
address start = __ pc();
|
||||
__ enter();
|
||||
|
||||
const int states_len = 16;
|
||||
const int step = 4;
|
||||
const Register state = c_rarg0;
|
||||
const Register key_stream = c_rarg1;
|
||||
const Register tmp_addr = t0;
|
||||
const Register length = t1;
|
||||
|
||||
// Organize vector registers in an array that facilitates
|
||||
// putting repetitive opcodes into loop structures below.
|
||||
const VectorRegister work_vrs[16] = {
|
||||
v0, v1, v2, v3, v4, v5, v6, v7,
|
||||
v8, v9, v10, v11, v12, v13, v14, v15
|
||||
};
|
||||
const VectorRegister tmp_vr = v16;
|
||||
const VectorRegister counter_vr = v17;
|
||||
|
||||
{
|
||||
// Put 16 here, as com.sun.crypto.providerChaCha20Cipher.KS_MAX_LEN is 1024
|
||||
// in java level.
|
||||
__ vsetivli(length, 16, Assembler::e32, Assembler::m1);
|
||||
}
|
||||
|
||||
// Load from source state.
|
||||
// Every element in source state is duplicated to all elements in the corresponding vector.
|
||||
__ mv(tmp_addr, state);
|
||||
for (int i = 0; i < states_len; i += 1) {
|
||||
__ vlse32_v(work_vrs[i], tmp_addr, zr);
|
||||
__ addi(tmp_addr, tmp_addr, step);
|
||||
}
|
||||
// Adjust counter for every individual block.
|
||||
__ vid_v(counter_vr);
|
||||
__ vadd_vv(work_vrs[12], work_vrs[12], counter_vr);
|
||||
|
||||
// Perform 10 iterations of the 8 quarter round set
|
||||
{
|
||||
const Register loop = t2; // share t2 with other non-overlapping usages.
|
||||
__ mv(loop, 10);
|
||||
__ BIND(L_Rounds);
|
||||
|
||||
chacha20_quarter_round(work_vrs[0], work_vrs[4], work_vrs[8], work_vrs[12], tmp_vr);
|
||||
chacha20_quarter_round(work_vrs[1], work_vrs[5], work_vrs[9], work_vrs[13], tmp_vr);
|
||||
chacha20_quarter_round(work_vrs[2], work_vrs[6], work_vrs[10], work_vrs[14], tmp_vr);
|
||||
chacha20_quarter_round(work_vrs[3], work_vrs[7], work_vrs[11], work_vrs[15], tmp_vr);
|
||||
|
||||
chacha20_quarter_round(work_vrs[0], work_vrs[5], work_vrs[10], work_vrs[15], tmp_vr);
|
||||
chacha20_quarter_round(work_vrs[1], work_vrs[6], work_vrs[11], work_vrs[12], tmp_vr);
|
||||
chacha20_quarter_round(work_vrs[2], work_vrs[7], work_vrs[8], work_vrs[13], tmp_vr);
|
||||
chacha20_quarter_round(work_vrs[3], work_vrs[4], work_vrs[9], work_vrs[14], tmp_vr);
|
||||
|
||||
__ sub(loop, loop, 1);
|
||||
__ bnez(loop, L_Rounds);
|
||||
}
|
||||
|
||||
// Add the original state into the end working state.
|
||||
// We do this by first duplicating every element in source state array to the corresponding
|
||||
// vector, then adding it to the post-loop working state.
|
||||
__ mv(tmp_addr, state);
|
||||
for (int i = 0; i < states_len; i += 1) {
|
||||
__ vlse32_v(tmp_vr, tmp_addr, zr);
|
||||
__ addi(tmp_addr, tmp_addr, step);
|
||||
__ vadd_vv(work_vrs[i], work_vrs[i], tmp_vr);
|
||||
}
|
||||
// Add the counter overlay onto work_vrs[12] at the end.
|
||||
__ vadd_vv(work_vrs[12], work_vrs[12], counter_vr);
|
||||
|
||||
// Store result to key stream.
|
||||
{
|
||||
const Register stride = t2; // share t2 with other non-overlapping usages.
|
||||
// Every block occupies 64 bytes, so we use 64 as stride of the vector store.
|
||||
__ mv(stride, 64);
|
||||
for (int i = 0; i < states_len; i += 1) {
|
||||
__ vsse32_v(work_vrs[i], key_stream, stride);
|
||||
__ addi(key_stream, key_stream, step);
|
||||
}
|
||||
}
|
||||
|
||||
// Return length of output key_stream
|
||||
__ slli(c_rarg0, length, 6);
|
||||
|
||||
__ leave();
|
||||
__ ret();
|
||||
|
||||
return (address) start;
|
||||
}
|
||||
|
||||
#if INCLUDE_JFR
|
||||
|
||||
static void jfr_prologue(address the_pc, MacroAssembler* _masm, Register thread) {
|
||||
@@ -4368,6 +4505,20 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
#endif // INCLUDE_JFR
|
||||
|
||||
// exception handler for upcall stubs
|
||||
address generate_upcall_stub_exception_handler() {
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
|
||||
address start = __ pc();
|
||||
|
||||
// Native caller has no idea how to handle exceptions,
|
||||
// so we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(x10); // return a exception oop in a0
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, UpcallLinker::handle_uncaught_exception));
|
||||
__ should_not_reach_here();
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
// Initialization
|
||||
@@ -4452,6 +4603,8 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::riscv::_method_entry_barrier = generate_method_entry_barrier();
|
||||
}
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
|
||||
StubRoutines::riscv::set_completed();
|
||||
}
|
||||
|
||||
@@ -4496,6 +4649,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress");
|
||||
StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB");
|
||||
}
|
||||
|
||||
if (UseChaCha20Intrinsics) {
|
||||
StubRoutines::_chacha20Block = generate_chacha20Block();
|
||||
}
|
||||
|
||||
#endif // COMPILER2_OR_JVMCI
|
||||
}
|
||||
|
||||
|
||||
@@ -1318,7 +1318,7 @@ void TemplateTable::idiv() {
|
||||
__ bind(no_div0);
|
||||
__ pop_i(x11);
|
||||
// x10 <== x11 idiv x10
|
||||
__ corrected_idivl(x10, x11, x10, /* want_remainder */ false);
|
||||
__ corrected_idivl(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true);
|
||||
}
|
||||
|
||||
void TemplateTable::irem() {
|
||||
@@ -1331,7 +1331,7 @@ void TemplateTable::irem() {
|
||||
__ bind(no_div0);
|
||||
__ pop_i(x11);
|
||||
// x10 <== x11 irem x10
|
||||
__ corrected_idivl(x10, x11, x10, /* want_remainder */ true);
|
||||
__ corrected_idivl(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true);
|
||||
}
|
||||
|
||||
void TemplateTable::lmul() {
|
||||
@@ -1350,7 +1350,7 @@ void TemplateTable::ldiv() {
|
||||
__ bind(no_div0);
|
||||
__ pop_l(x11);
|
||||
// x10 <== x11 ldiv x10
|
||||
__ corrected_idivq(x10, x11, x10, /* want_remainder */ false);
|
||||
__ corrected_idivq(x10, x11, x10, /* want_remainder */ false, /* is_signed */ true);
|
||||
}
|
||||
|
||||
void TemplateTable::lrem() {
|
||||
@@ -1363,7 +1363,7 @@ void TemplateTable::lrem() {
|
||||
__ bind(no_div0);
|
||||
__ pop_l(x11);
|
||||
// x10 <== x11 lrem x10
|
||||
__ corrected_idivq(x10, x11, x10, /* want_remainder */ true);
|
||||
__ corrected_idivq(x10, x11, x10, /* want_remainder */ true, /* is_signed */ true);
|
||||
}
|
||||
|
||||
void TemplateTable::lshl() {
|
||||
|
||||
@@ -114,7 +114,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
__ block_comment("} restore_callee_saved_regs ");
|
||||
}
|
||||
|
||||
static const int upcall_stub_code_base_size = 2048;
|
||||
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,
|
||||
@@ -218,6 +218,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
__ block_comment("{ on_entry");
|
||||
__ la(c_rarg0, Address(sp, frame_data_offset));
|
||||
__ movptr(c_rarg1, (intptr_t) receiver);
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, UpcallLinker::on_entry));
|
||||
__ mv(xthread, x10);
|
||||
__ reinit_heapbase();
|
||||
@@ -255,9 +256,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
__ block_comment("{ receiver ");
|
||||
__ movptr(shuffle_reg, (intptr_t) receiver);
|
||||
__ resolve_jobject(shuffle_reg, t0, t1);
|
||||
__ mv(j_rarg0, shuffle_reg);
|
||||
__ get_vm_result(j_rarg0, xthread);
|
||||
__ block_comment("} receiver ");
|
||||
|
||||
__ mov_metadata(xmethod, entry);
|
||||
@@ -326,17 +325,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__ block_comment("{ exception handler");
|
||||
|
||||
intptr_t exception_handler_offset = __ pc() - start;
|
||||
|
||||
// Native caller has no idea how to handle exceptions,
|
||||
// so we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(x10); // return a exception oop in a0
|
||||
__ rt_call(CAST_FROM_FN_PTR(address, UpcallLinker::handle_uncaught_exception));
|
||||
__ should_not_reach_here();
|
||||
|
||||
__ block_comment("} exception handler");
|
||||
__ flush();
|
||||
|
||||
#ifndef PRODUCT
|
||||
@@ -352,7 +340,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
UpcallStub* blob
|
||||
= UpcallStub::create(name,
|
||||
&buffer,
|
||||
exception_handler_offset,
|
||||
receiver,
|
||||
in_ByteSize(frame_data_offset));
|
||||
#ifndef PRODUCT
|
||||
|
||||
@@ -182,10 +182,23 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
|
||||
}
|
||||
|
||||
if (UseVectorizedMismatchIntrinsic) {
|
||||
warning("VectorizedMismatch intrinsic is not available on this CPU.");
|
||||
FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(UseMD5Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseMD5Intrinsics, true);
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(UseCopySignIntrinsic)) {
|
||||
FLAG_SET_DEFAULT(UseCopySignIntrinsic, true);
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(UseSignumIntrinsic)) {
|
||||
FLAG_SET_DEFAULT(UseSignumIntrinsic, true);
|
||||
}
|
||||
|
||||
if (UseRVV) {
|
||||
if (!ext_V.enabled()) {
|
||||
warning("RVV is not supported on this CPU");
|
||||
@@ -248,6 +261,16 @@ void VM_Version::initialize() {
|
||||
warning("Block zeroing is not available");
|
||||
FLAG_SET_DEFAULT(UseBlockZeroing, false);
|
||||
}
|
||||
if (UseRVV) {
|
||||
if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseChaCha20Intrinsics, true);
|
||||
}
|
||||
} else if (UseChaCha20Intrinsics) {
|
||||
if (!FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
|
||||
warning("Chacha20 intrinsic requires RVV instructions (not available on this CPU)");
|
||||
}
|
||||
FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
|
||||
}
|
||||
|
||||
#ifdef COMPILER2
|
||||
c2_initialize();
|
||||
|
||||
@@ -140,7 +140,8 @@ class RelAddr {
|
||||
if ((target == nullptr) || (target == pc)) {
|
||||
return 0; // Yet unknown branch destination.
|
||||
} else {
|
||||
guarantee(is_in_range_of_RelAddr(target, pc, shortForm), "target not within reach");
|
||||
guarantee(is_in_range_of_RelAddr(target, pc, shortForm),
|
||||
"target not within reach at " INTPTR_FORMAT ", distance = " INTX_FORMAT, p2i(pc), (target - pc) );
|
||||
return (int)((target - pc)>>1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
load_klass(tmp, Roop);
|
||||
testbit(Address(tmp, Klass::access_flags_offset()), exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
|
||||
z_btrue(slow_case);
|
||||
branch_optimized(Assembler::bcondAllOne, slow_case);
|
||||
}
|
||||
|
||||
assert(LockingMode != LM_MONITOR, "LM_MONITOR is already handled, by emit_lock()");
|
||||
@@ -170,7 +170,7 @@ void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rb
|
||||
z_lg(Rmark, Address(Roop, hdr_offset));
|
||||
z_lgr(tmp, Rmark);
|
||||
z_nill(tmp, markWord::monitor_value);
|
||||
z_brnz(slow_case);
|
||||
branch_optimized(Assembler::bcondNotZero, slow_case);
|
||||
lightweight_unlock(Roop, Rmark, tmp, slow_case);
|
||||
} else if (LockingMode == LM_LEGACY) {
|
||||
// Test if object header is pointing to the displaced header, and if so, restore
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "oops/markWord.hpp"
|
||||
#include "oops/methodCounters.hpp"
|
||||
#include "oops/methodData.hpp"
|
||||
#include "oops/resolvedFieldEntry.hpp"
|
||||
#include "oops/resolvedIndyEntry.hpp"
|
||||
#include "prims/jvmtiExport.hpp"
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
@@ -349,16 +350,45 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Regis
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::load_resolved_indy_entry(Register cache, Register index) {
|
||||
// Get index out of bytecode pointer, get_cache_entry_pointer_at_bcp
|
||||
// Get index out of bytecode pointer.
|
||||
get_cache_index_at_bcp(index, 1, sizeof(u4));
|
||||
// Get address of invokedynamic array
|
||||
|
||||
// Get the address of the ResolvedIndyEntry array
|
||||
get_constant_pool_cache(cache);
|
||||
z_lg(cache, Address(cache, in_bytes(ConstantPoolCache::invokedynamic_entries_offset())));
|
||||
// Scale the index to be the entry index * sizeof(ResolvedInvokeDynamicInfo)
|
||||
z_sllg(index, index, exact_log2(sizeof(ResolvedIndyEntry)));
|
||||
|
||||
// Scale the index to form a byte offset into the ResolvedIndyEntry array
|
||||
size_t entry_size = sizeof(ResolvedIndyEntry);
|
||||
if (is_power_of_2(entry_size)) {
|
||||
z_sllg(index, index, exact_log2(entry_size));
|
||||
} else {
|
||||
z_mghi(index, entry_size);
|
||||
}
|
||||
|
||||
// Calculate the final field address.
|
||||
z_la(cache, Array<ResolvedIndyEntry>::base_offset_in_bytes(), index, cache);
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::load_field_entry(Register cache, Register index, int bcp_offset) {
|
||||
// Get field index out of bytecode pointer.
|
||||
get_cache_index_at_bcp(index, bcp_offset, sizeof(u2));
|
||||
|
||||
// Get the address of the ResolvedFieldEntry array.
|
||||
get_constant_pool_cache(cache);
|
||||
z_lg(cache, Address(cache, in_bytes(ConstantPoolCache::field_entries_offset())));
|
||||
|
||||
// Scale the index to form a byte offset into the ResolvedFieldEntry array
|
||||
size_t entry_size = sizeof(ResolvedFieldEntry);
|
||||
if (is_power_of_2(entry_size)) {
|
||||
z_sllg(index, index, exact_log2(entry_size));
|
||||
} else {
|
||||
z_mghi(index, entry_size);
|
||||
}
|
||||
|
||||
// Calculate the final field address.
|
||||
z_la(cache, Array<ResolvedFieldEntry>::base_offset_in_bytes(), index, cache);
|
||||
}
|
||||
|
||||
// Kills Z_R0_scratch.
|
||||
void InterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache,
|
||||
Register cpe_offset,
|
||||
|
||||
@@ -113,6 +113,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
|
||||
void get_cache_and_index_at_bcp(Register cache, Register cpe_offset, int bcp_offset, size_t index_size = sizeof(u2));
|
||||
void load_resolved_indy_entry(Register cache, Register index);
|
||||
void load_field_entry(Register cache, Register index, int bcp_offset = 1);
|
||||
void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register cpe_offset, Register bytecode,
|
||||
int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
|
||||
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/javaThread.hpp"
|
||||
@@ -3094,6 +3095,21 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
#endif // INCLUDE_JFR
|
||||
|
||||
// exception handler for upcall stubs
|
||||
address generate_upcall_stub_exception_handler() {
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
|
||||
address start = __ pc();
|
||||
|
||||
// Native caller has no idea how to handle exceptions,
|
||||
// so we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(Z_ARG1);
|
||||
__ load_const_optimized(Z_R1_scratch, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception));
|
||||
__ call_c(Z_R1_scratch);
|
||||
__ should_not_reach_here();
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
void generate_initial_stubs() {
|
||||
// Generates all stubs and initializes the entry points.
|
||||
|
||||
@@ -3174,6 +3190,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
StubRoutines::zarch::_nmethod_entry_barrier = generate_nmethod_entry_barrier();
|
||||
}
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
}
|
||||
|
||||
void generate_compiler_stubs() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -114,7 +114,7 @@ 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; // depends on GC (resolve_jobject)
|
||||
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,
|
||||
BasicType* in_sig_bt, int total_in_args,
|
||||
@@ -202,6 +202,7 @@ 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");
|
||||
@@ -212,8 +213,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
__ block_comment("{ receiver ");
|
||||
__ load_const_optimized(Z_ARG1, (intptr_t)receiver);
|
||||
__ resolve_jobject(Z_ARG1, Z_tmp_1, Z_tmp_2);
|
||||
__ get_vm_result(Z_ARG1);
|
||||
__ block_comment("} receiver ");
|
||||
|
||||
__ load_const_optimized(Z_method, (intptr_t)entry);
|
||||
@@ -266,19 +266,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__ block_comment("{ exception handler");
|
||||
|
||||
intptr_t exception_handler_offset = __ pc() - start;
|
||||
|
||||
// Native caller has no idea how to handle exceptions,
|
||||
// so we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(Z_ARG1);
|
||||
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception));
|
||||
__ call_c(call_target_address);
|
||||
__ should_not_reach_here();
|
||||
|
||||
__ block_comment("} exception handler");
|
||||
|
||||
_masm->flush();
|
||||
|
||||
#ifndef PRODUCT
|
||||
@@ -293,7 +280,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
UpcallStub* blob
|
||||
= UpcallStub::create(name,
|
||||
&buffer,
|
||||
exception_handler_offset,
|
||||
receiver,
|
||||
in_ByteSize(frame_data_offset));
|
||||
#ifndef PRODUCT
|
||||
|
||||
@@ -1332,6 +1332,11 @@ void Assembler::addb(Address dst, Register src) {
|
||||
emit_operand(src, dst, 0);
|
||||
}
|
||||
|
||||
void Assembler::addb(Register dst, int imm8) {
|
||||
(void) prefix_and_encode(dst->encoding(), true);
|
||||
emit_arith_b(0x80, 0xC0, dst, imm8);
|
||||
}
|
||||
|
||||
void Assembler::addw(Register dst, Register src) {
|
||||
emit_int8(0x66);
|
||||
(void)prefix_and_encode(dst->encoding(), src->encoding());
|
||||
@@ -5319,6 +5324,18 @@ void Assembler::vpshufb(XMMRegister dst, XMMRegister nds, XMMRegister src, int v
|
||||
emit_int16(0x00, (0xC0 | encode));
|
||||
}
|
||||
|
||||
void Assembler::vpshufb(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
assert(vector_len == AVX_128bit ? VM_Version::supports_avx() :
|
||||
vector_len == AVX_256bit ? VM_Version::supports_avx2() :
|
||||
vector_len == AVX_512bit ? VM_Version::supports_avx512bw() : 0, "");
|
||||
InstructionMark im(this);
|
||||
InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
|
||||
attributes.set_address_attributes(/* tuple_type */ EVEX_FVM, /* input_size_in_bits */ EVEX_NObit);
|
||||
simd_prefix(dst, nds, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
|
||||
emit_int8(0x00);
|
||||
emit_operand(dst, src, 0);
|
||||
}
|
||||
|
||||
void Assembler::pshufb(XMMRegister dst, Address src) {
|
||||
assert(VM_Version::supports_ssse3(), "");
|
||||
InstructionMark im(this);
|
||||
|
||||
@@ -986,6 +986,7 @@ private:
|
||||
|
||||
void addb(Address dst, int imm8);
|
||||
void addb(Address dst, Register src);
|
||||
void addb(Register dst, int imm8);
|
||||
void addw(Register dst, Register src);
|
||||
void addw(Address dst, int imm16);
|
||||
void addw(Address dst, Register src);
|
||||
@@ -1952,6 +1953,7 @@ private:
|
||||
void pshufb(XMMRegister dst, XMMRegister src);
|
||||
void pshufb(XMMRegister dst, Address src);
|
||||
void vpshufb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpshufb(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void evpshufb(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len);
|
||||
|
||||
|
||||
|
||||
@@ -3853,13 +3853,11 @@ void C2_MacroAssembler::count_positives(Register ary1, Register len,
|
||||
VM_Version::supports_bmi2()) {
|
||||
|
||||
Label test_64_loop, test_tail, BREAK_LOOP;
|
||||
Register tmp3_aliased = len;
|
||||
|
||||
movl(tmp1, len);
|
||||
vpxor(vec2, vec2, vec2, Assembler::AVX_512bit);
|
||||
|
||||
andl(tmp1, 64 - 1); // tail count (in chars) 0x3F
|
||||
andl(len, ~(64 - 1)); // vector count (in chars)
|
||||
andl(tmp1, 0x0000003f); // tail count (in chars) 0x3F
|
||||
andl(len, 0xffffffc0); // vector count (in chars)
|
||||
jccb(Assembler::zero, test_tail);
|
||||
|
||||
lea(ary1, Address(ary1, len, Address::times_1));
|
||||
@@ -3879,12 +3877,17 @@ void C2_MacroAssembler::count_positives(Register ary1, Register len,
|
||||
testl(tmp1, -1);
|
||||
jcc(Assembler::zero, DONE);
|
||||
|
||||
|
||||
// check the tail for absense of negatives
|
||||
// ~(~0 << len) applied up to two times (for 32-bit scenario)
|
||||
#ifdef _LP64
|
||||
mov64(tmp3_aliased, 0xFFFFFFFFFFFFFFFF);
|
||||
shlxq(tmp3_aliased, tmp3_aliased, tmp1);
|
||||
notq(tmp3_aliased);
|
||||
kmovql(mask2, tmp3_aliased);
|
||||
{
|
||||
Register tmp3_aliased = len;
|
||||
mov64(tmp3_aliased, 0xFFFFFFFFFFFFFFFF);
|
||||
shlxq(tmp3_aliased, tmp3_aliased, tmp1);
|
||||
notq(tmp3_aliased);
|
||||
kmovql(mask2, tmp3_aliased);
|
||||
}
|
||||
#else
|
||||
Label k_init;
|
||||
jmp(k_init);
|
||||
@@ -3916,8 +3919,13 @@ void C2_MacroAssembler::count_positives(Register ary1, Register len,
|
||||
ktestq(mask1, mask2);
|
||||
jcc(Assembler::zero, DONE);
|
||||
|
||||
// do a full check for negative registers in the tail
|
||||
movl(len, tmp1); // tmp1 holds low 6-bit from original len;
|
||||
// ary1 already pointing to the right place
|
||||
jmpb(TAIL_START);
|
||||
|
||||
bind(BREAK_LOOP);
|
||||
// At least one byte in the last 64 bytes is negative.
|
||||
// At least one byte in the last 64 byte block was negative.
|
||||
// Set up to look at the last 64 bytes as if they were a tail
|
||||
lea(ary1, Address(ary1, len, Address::times_1));
|
||||
addptr(result, len);
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
// Entry frames
|
||||
#ifdef AMD64
|
||||
#ifdef _WIN64
|
||||
entry_frame_after_call_words = 60,
|
||||
entry_frame_after_call_words = 28,
|
||||
entry_frame_call_wrapper_offset = 2,
|
||||
|
||||
arg_reg_save_area_bytes = 32, // Register argument save area
|
||||
|
||||
@@ -9280,6 +9280,17 @@ void MacroAssembler::evporq(XMMRegister dst, XMMRegister nds, AddressLiteral src
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vpshufb(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register rscratch) {
|
||||
assert(rscratch != noreg || always_reachable(src), "missing");
|
||||
|
||||
if (reachable(src)) {
|
||||
vpshufb(dst, nds, as_Address(src), vector_len);
|
||||
} else {
|
||||
lea(rscratch, src);
|
||||
vpshufb(dst, nds, Address(rscratch, 0), vector_len);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vpternlogq(XMMRegister dst, int imm8, XMMRegister src2, AddressLiteral src3, int vector_len, Register rscratch) {
|
||||
assert(rscratch != noreg || always_reachable(src3), "missing");
|
||||
|
||||
|
||||
@@ -1795,6 +1795,9 @@ public:
|
||||
using Assembler::evporq;
|
||||
void evporq(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register rscratch = noreg);
|
||||
|
||||
using Assembler::vpshufb;
|
||||
void vpshufb(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register rscratch = noreg);
|
||||
|
||||
using Assembler::vpternlogq;
|
||||
void vpternlogq(XMMRegister dst, int imm8, XMMRegister src2, AddressLiteral src3, int vector_len, Register rscratch = noreg);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "gc/shared/gc_globals.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "prims/jvmtiExport.hpp"
|
||||
#include "prims/upcallLinker.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/javaThread.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
@@ -106,10 +107,8 @@
|
||||
// [ return_from_Java ] <--- rsp
|
||||
// [ argument word n ]
|
||||
// ...
|
||||
// -60 [ argument word 1 ]
|
||||
// -59 [ saved xmm31 ] <--- rsp after_call
|
||||
// [ saved xmm16-xmm30 ] (EVEX enabled, else the space is blank)
|
||||
// -27 [ saved xmm15 ]
|
||||
// -28 [ argument word 1 ]
|
||||
// -27 [ saved xmm15 ] <--- rsp after_call
|
||||
// [ saved xmm7-xmm14 ]
|
||||
// -9 [ saved xmm6 ] (each xmm register takes 2 slots)
|
||||
// -7 [ saved r15 ]
|
||||
@@ -137,7 +136,7 @@
|
||||
#ifdef _WIN64
|
||||
enum call_stub_layout {
|
||||
xmm_save_first = 6, // save from xmm6
|
||||
xmm_save_last = 31, // to xmm31
|
||||
xmm_save_last = 15, // to xmm15
|
||||
xmm_save_base = -9,
|
||||
rsp_after_call_off = xmm_save_base - 2 * (xmm_save_last - xmm_save_first), // -27
|
||||
r15_off = -7,
|
||||
@@ -237,17 +236,8 @@ address StubGenerator::generate_call_stub(address& return_address) {
|
||||
|
||||
#ifdef _WIN64
|
||||
int last_reg = 15;
|
||||
if (UseAVX > 2) {
|
||||
last_reg = 31;
|
||||
}
|
||||
if (VM_Version::supports_evex()) {
|
||||
for (int i = xmm_save_first; i <= last_reg; i++) {
|
||||
__ vextractf32x4(xmm_save(i), as_XMMRegister(i), 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = xmm_save_first; i <= last_reg; i++) {
|
||||
__ movdqu(xmm_save(i), as_XMMRegister(i));
|
||||
}
|
||||
for (int i = xmm_save_first; i <= last_reg; i++) {
|
||||
__ movdqu(xmm_save(i), as_XMMRegister(i));
|
||||
}
|
||||
|
||||
const Address rdi_save(rbp, rdi_off * wordSize);
|
||||
@@ -370,14 +360,8 @@ address StubGenerator::generate_call_stub(address& return_address) {
|
||||
// restore regs belonging to calling function
|
||||
#ifdef _WIN64
|
||||
// emit the restores for xmm regs
|
||||
if (VM_Version::supports_evex()) {
|
||||
for (int i = xmm_save_first; i <= last_reg; i++) {
|
||||
__ vinsertf32x4(as_XMMRegister(i), as_XMMRegister(i), xmm_save(i), 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = xmm_save_first; i <= last_reg; i++) {
|
||||
__ movdqu(as_XMMRegister(i), xmm_save(i));
|
||||
}
|
||||
for (int i = xmm_save_first; i <= last_reg; i++) {
|
||||
__ movdqu(as_XMMRegister(i), xmm_save(i));
|
||||
}
|
||||
#endif
|
||||
__ movptr(r15, r15_save);
|
||||
@@ -3904,6 +3888,24 @@ address StubGenerator::generate_throw_exception(const char* name,
|
||||
return stub->entry_point();
|
||||
}
|
||||
|
||||
// exception handler for upcall stubs
|
||||
address StubGenerator::generate_upcall_stub_exception_handler() {
|
||||
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
|
||||
address start = __ pc();
|
||||
|
||||
// native caller has no idea how to handle exceptions
|
||||
// we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(rax);
|
||||
__ vzeroupper();
|
||||
__ mov(c_rarg0, rax);
|
||||
__ andptr(rsp, -StackAlignmentInBytes); // align stack as required by ABI
|
||||
__ subptr(rsp, frame::arg_reg_save_area_bytes); // windows
|
||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, UpcallLinker::handle_uncaught_exception)));
|
||||
__ should_not_reach_here();
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
void StubGenerator::create_control_words() {
|
||||
// Round to nearest, 64-bit mode, exceptions masked
|
||||
StubRoutines::x86::_mxcsr_std = 0x1F80;
|
||||
@@ -4056,6 +4058,8 @@ void StubGenerator::generate_final_stubs() {
|
||||
if (UseVectorizedMismatchIntrinsic) {
|
||||
StubRoutines::_vectorizedMismatch = generate_vectorizedMismatch();
|
||||
}
|
||||
|
||||
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
|
||||
}
|
||||
|
||||
void StubGenerator::generate_compiler_stubs() {
|
||||
@@ -4189,6 +4193,26 @@ void StubGenerator::generate_compiler_stubs() {
|
||||
= CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_square);
|
||||
}
|
||||
|
||||
// Load x86_64_sort library on supported hardware to enable avx512 sort and partition intrinsics
|
||||
if (VM_Version::is_intel() && VM_Version::supports_avx512dq()) {
|
||||
void *libsimdsort = nullptr;
|
||||
char ebuf_[1024];
|
||||
char dll_name_simd_sort[JVM_MAXPATHLEN];
|
||||
if (os::dll_locate_lib(dll_name_simd_sort, sizeof(dll_name_simd_sort), Arguments::get_dll_dir(), "simdsort")) {
|
||||
libsimdsort = os::dll_load(dll_name_simd_sort, ebuf_, sizeof ebuf_);
|
||||
}
|
||||
// Get addresses for avx512 sort and partition routines
|
||||
if (libsimdsort != nullptr) {
|
||||
log_info(library)("Loaded library %s, handle " INTPTR_FORMAT, JNI_LIB_PREFIX "simdsort" JNI_LIB_SUFFIX, p2i(libsimdsort));
|
||||
|
||||
snprintf(ebuf_, sizeof(ebuf_), "avx512_sort");
|
||||
StubRoutines::_array_sort = (address)os::dll_lookup(libsimdsort, ebuf_);
|
||||
|
||||
snprintf(ebuf_, sizeof(ebuf_), "avx512_partition");
|
||||
StubRoutines::_array_partition = (address)os::dll_lookup(libsimdsort, ebuf_);
|
||||
}
|
||||
}
|
||||
|
||||
// Get svml stub routine addresses
|
||||
void *libjsvml = nullptr;
|
||||
char ebuf[1024];
|
||||
|
||||
@@ -327,6 +327,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
void aesgcm_encrypt(Register in, Register len, Register ct, Register out, Register key,
|
||||
Register state, Register subkeyHtbl, Register avx512_subkeyHtbl, Register counter);
|
||||
|
||||
// AVX2 AES Galois Counter Mode implementation
|
||||
address generate_avx2_galoisCounterMode_AESCrypt();
|
||||
void aesgcm_avx2(Register in, Register len, Register ct, Register out, Register key,
|
||||
Register state, Register subkeyHtbl, Register counter);
|
||||
|
||||
// Vector AES Counter implementation
|
||||
address generate_counterMode_VectorAESCrypt();
|
||||
@@ -353,6 +357,17 @@ class StubGenerator: public StubCodeGenerator {
|
||||
XMMRegister aad_hashx, Register in, Register out, Register data, Register pos, bool reduction,
|
||||
XMMRegister addmask, bool no_ghash_input, Register rounds, Register ghash_pos,
|
||||
bool final_reduction, int index, XMMRegister counter_inc_mask);
|
||||
// AVX2 AES-GCM related functions
|
||||
void initial_blocks_avx2(XMMRegister ctr, Register rounds, Register key, Register len,
|
||||
Register in, Register out, Register ct, XMMRegister aad_hashx, Register pos);
|
||||
void gfmul_avx2(XMMRegister GH, XMMRegister HK);
|
||||
void generateHtbl_8_block_avx2(Register htbl);
|
||||
void ghash8_encrypt8_parallel_avx2(Register key, Register subkeyHtbl, XMMRegister ctr_blockx, Register in,
|
||||
Register out, Register ct, Register pos, bool out_order, Register rounds,
|
||||
XMMRegister xmm1, XMMRegister xmm2, XMMRegister xmm3, XMMRegister xmm4,
|
||||
XMMRegister xmm5, XMMRegister xmm6, XMMRegister xmm7, XMMRegister xmm8);
|
||||
void ghash_last_8_avx2(Register subkeyHtbl);
|
||||
|
||||
// Load key and shuffle operation
|
||||
void ev_load_key(XMMRegister xmmdst, Register key, int offset, XMMRegister xmm_shuf_mask);
|
||||
void ev_load_key(XMMRegister xmmdst, Register key, int offset, Register rscratch);
|
||||
@@ -550,6 +565,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Register arg1 = noreg,
|
||||
Register arg2 = noreg);
|
||||
|
||||
// shared exception handler for FFM upcall stubs
|
||||
address generate_upcall_stub_exception_handler();
|
||||
|
||||
void create_control_words();
|
||||
|
||||
// Initialization
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2019, 2023, Intel Corporation. All rights reserved.
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -81,6 +81,30 @@ static address counter_mask_linc1_addr() {
|
||||
return (address)COUNTER_MASK_LINC1;
|
||||
}
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) uint64_t COUNTER_MASK_LINC1F[] = {
|
||||
0x0000000000000000UL, 0x0100000000000000UL,
|
||||
};
|
||||
|
||||
static address counter_mask_linc1f_addr() {
|
||||
return (address)COUNTER_MASK_LINC1F;
|
||||
}
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) uint64_t COUNTER_MASK_LINC2[] = {
|
||||
0x0000000000000002UL, 0x0000000000000000UL,
|
||||
};
|
||||
|
||||
static address counter_mask_linc2_addr() {
|
||||
return (address)COUNTER_MASK_LINC2;
|
||||
}
|
||||
|
||||
ATTRIBUTE_ALIGNED(16) uint64_t COUNTER_MASK_LINC2F[] = {
|
||||
0x0000000000000000UL, 0x0200000000000000UL,
|
||||
};
|
||||
|
||||
static address counter_mask_linc2f_addr() {
|
||||
return (address)COUNTER_MASK_LINC2F;
|
||||
}
|
||||
|
||||
ATTRIBUTE_ALIGNED(64) static const uint64_t COUNTER_MASK_LINC4[] = {
|
||||
0x0000000000000004UL, 0x0000000000000000UL,
|
||||
0x0000000000000004UL, 0x0000000000000000UL,
|
||||
@@ -163,6 +187,9 @@ void StubGenerator::generate_aes_stubs() {
|
||||
StubRoutines::_galoisCounterMode_AESCrypt = generate_galoisCounterMode_AESCrypt();
|
||||
} else {
|
||||
StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
|
||||
if (VM_Version::supports_avx2()) {
|
||||
StubRoutines::_galoisCounterMode_AESCrypt = generate_avx2_galoisCounterMode_AESCrypt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,6 +291,90 @@ address StubGenerator::generate_galoisCounterMode_AESCrypt() {
|
||||
return start;
|
||||
}
|
||||
|
||||
// AVX2 Vector AES Galois Counter Mode implementation.
|
||||
//
|
||||
// Inputs: Windows | Linux
|
||||
// in = rcx (c_rarg0) | rsi (c_rarg0)
|
||||
// len = rdx (c_rarg1) | rdi (c_rarg1)
|
||||
// ct = r8 (c_rarg2) | rdx (c_rarg2)
|
||||
// out = r9 (c_rarg3) | rcx (c_rarg3)
|
||||
// key = rdi | r8 (c_rarg4)
|
||||
// state = r13 | r9 (c_rarg5)
|
||||
// subkeyHtbl = r11 | r11
|
||||
// counter = rsi | r12
|
||||
//
|
||||
// Output:
|
||||
// rax - number of processed bytes
|
||||
address StubGenerator::generate_avx2_galoisCounterMode_AESCrypt() {
|
||||
__ align(CodeEntryAlignment);
|
||||
StubCodeMark mark(this, "StubRoutines", "galoisCounterMode_AESCrypt");
|
||||
address start = __ pc();
|
||||
|
||||
const Register in = c_rarg0;
|
||||
const Register len = c_rarg1;
|
||||
const Register ct = c_rarg2;
|
||||
const Register out = c_rarg3;
|
||||
// and updated with the incremented counter in the end
|
||||
#ifndef _WIN64
|
||||
const Register key = c_rarg4;
|
||||
const Register state = c_rarg5;
|
||||
const Address subkeyH_mem(rbp, 2 * wordSize);
|
||||
const Register subkeyHtbl = r11;
|
||||
const Address counter_mem(rbp, 3 * wordSize);
|
||||
const Register counter = r12;
|
||||
#else
|
||||
const Address key_mem(rbp, 6 * wordSize);
|
||||
const Register key = rdi;
|
||||
const Address state_mem(rbp, 7 * wordSize);
|
||||
const Register state = r13;
|
||||
const Address subkeyH_mem(rbp, 8 * wordSize);
|
||||
const Register subkeyHtbl = r11;
|
||||
const Address counter_mem(rbp, 9 * wordSize);
|
||||
const Register counter = rsi;
|
||||
#endif
|
||||
__ enter();
|
||||
// Save state before entering routine
|
||||
__ push(r12);
|
||||
__ push(r13);
|
||||
__ push(r14);
|
||||
__ push(r15);
|
||||
__ push(rbx);
|
||||
#ifdef _WIN64
|
||||
// on win64, fill len_reg from stack position
|
||||
__ push(rsi);
|
||||
__ push(rdi);
|
||||
__ movptr(key, key_mem);
|
||||
__ movptr(state, state_mem);
|
||||
#endif
|
||||
__ movptr(subkeyHtbl, subkeyH_mem);
|
||||
__ movptr(counter, counter_mem);
|
||||
|
||||
// Save rsp
|
||||
__ movq(r14, rsp);
|
||||
// Align stack
|
||||
__ andq(rsp, -64);
|
||||
__ subptr(rsp, 16 * longSize); // Create space on the stack for saving AES entries
|
||||
|
||||
aesgcm_avx2(in, len, ct, out, key, state, subkeyHtbl, counter);
|
||||
__ vzeroupper();
|
||||
__ movq(rsp, r14);
|
||||
// Restore state before leaving routine
|
||||
#ifdef _WIN64
|
||||
__ pop(rdi);
|
||||
__ pop(rsi);
|
||||
#endif
|
||||
__ pop(rbx);
|
||||
__ pop(r15);
|
||||
__ pop(r14);
|
||||
__ pop(r13);
|
||||
__ pop(r12);
|
||||
|
||||
__ leave(); // required for proper stackwalking of RuntimeStub frame
|
||||
__ ret(0);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
// Vector AES Counter implementation
|
||||
address StubGenerator::generate_counterMode_VectorAESCrypt() {
|
||||
__ align(CodeEntryAlignment);
|
||||
@@ -3181,4 +3292,544 @@ void StubGenerator::aesgcm_encrypt(Register in, Register len, Register ct, Regis
|
||||
__ movq(rax, pos);
|
||||
}
|
||||
|
||||
//Implements data * hashkey mod (128, 127, 126, 121, 0)
|
||||
//Inputs:
|
||||
//GH and HK - 128 bits each
|
||||
//Output:
|
||||
//GH = GH * Hashkey mod poly
|
||||
//Temp registers: xmm1, xmm2, xmm3, r15
|
||||
void StubGenerator::gfmul_avx2(XMMRegister GH, XMMRegister HK) {
|
||||
const XMMRegister T1 = xmm1;
|
||||
const XMMRegister T2 = xmm2;
|
||||
const XMMRegister T3 = xmm3;
|
||||
|
||||
__ vpclmulqdq(T1, GH, HK, 0x11); // %%T1 = a1*b1
|
||||
__ vpclmulqdq(T2, GH, HK, 0x00); // %%T2 = a0*b0
|
||||
__ vpclmulqdq(T3, GH, HK, 0x01); // %%T3 = a1*b0
|
||||
__ vpclmulqdq(GH, GH, HK, 0x10); // %%GH = a0*b1
|
||||
__ vpxor(GH, GH, T3, Assembler::AVX_128bit);
|
||||
|
||||
__ vpsrldq(T3, GH, 8, Assembler::AVX_128bit); // shift-R %%GH 2 DWs
|
||||
__ vpslldq(GH, GH, 8, Assembler::AVX_128bit); // shift-L %%GH 2 DWs
|
||||
|
||||
__ vpxor(T1, T1, T3, Assembler::AVX_128bit);
|
||||
__ vpxor(GH, GH, T2, Assembler::AVX_128bit);
|
||||
|
||||
//first phase of the reduction
|
||||
__ movdqu(T3, ExternalAddress(ghash_polynomial_reduction_addr()), r15 /*rscratch*/);
|
||||
__ vpclmulqdq(T2, T3, GH, 0x01);
|
||||
__ vpslldq(T2, T2, 8, Assembler::AVX_128bit); // shift-L %%T2 2 DWs
|
||||
|
||||
__ vpxor(GH, GH, T2, Assembler::AVX_128bit); // first phase of the reduction complete
|
||||
//second phase of the reduction
|
||||
__ vpclmulqdq(T2, T3, GH, 0x00);
|
||||
__ vpsrldq(T2, T2, 4, Assembler::AVX_128bit); // shift-R %%T2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R)
|
||||
|
||||
__ vpclmulqdq(GH, T3, GH, 0x10);
|
||||
__ vpslldq(GH, GH, 4, Assembler::AVX_128bit); // shift-L %%GH 1 DW (Shift-L 1-DW to obtain result with no shifts)
|
||||
|
||||
__ vpxor(GH, GH, T2, Assembler::AVX_128bit); // second phase of the reduction complete
|
||||
__ vpxor(GH, GH, T1, Assembler::AVX_128bit); // the result is in %%GH
|
||||
}
|
||||
|
||||
//Generate 8 constants from the given subkeyH.
|
||||
//Input:
|
||||
//htbl - table containing the initial subkeyH
|
||||
//Output:
|
||||
//htbl - containing 8 H constants
|
||||
//Temp registers: xmm0, xmm1, xmm2, xmm3, xmm6, xmm11, xmm12, r15, rbx
|
||||
void StubGenerator::generateHtbl_8_block_avx2(Register htbl) {
|
||||
const XMMRegister HK = xmm6;
|
||||
|
||||
__ movdqu(HK, Address(htbl, 0));
|
||||
__ movdqu(xmm1, ExternalAddress(ghash_long_swap_mask_addr()), rbx /*rscratch*/);
|
||||
__ vpshufb(HK, HK, xmm1, Assembler::AVX_128bit);
|
||||
|
||||
__ movdqu(xmm11, ExternalAddress(ghash_polynomial_addr()), rbx /*rscratch*/);
|
||||
__ movdqu(xmm12, ExternalAddress(ghash_polynomial_two_one_addr()), rbx /*rscratch*/);
|
||||
// Compute H ^ 2 from the input subkeyH
|
||||
__ vpsrlq(xmm1, xmm6, 63, Assembler::AVX_128bit);
|
||||
__ vpsllq(xmm6, xmm6, 1, Assembler::AVX_128bit);
|
||||
__ vpslldq(xmm2, xmm1, 8, Assembler::AVX_128bit);
|
||||
__ vpsrldq(xmm1, xmm1, 8, Assembler::AVX_128bit);
|
||||
|
||||
__ vpor(xmm6, xmm6, xmm2, Assembler::AVX_128bit);
|
||||
|
||||
__ vpshufd(xmm2, xmm1, 0x24, Assembler::AVX_128bit);
|
||||
__ vpcmpeqd(xmm2, xmm2, xmm12, Assembler::AVX_128bit);
|
||||
__ vpand(xmm2, xmm2, xmm11, Assembler::AVX_128bit);
|
||||
__ vpxor(xmm6, xmm6, xmm2, Assembler::AVX_128bit);
|
||||
__ movdqu(Address(htbl, 1 * 16), xmm6); // H * 2
|
||||
__ movdqu(xmm0, xmm6);
|
||||
for (int i = 2; i < 9; i++) {
|
||||
gfmul_avx2(xmm6, xmm0);
|
||||
__ movdqu(Address(htbl, i * 16), xmm6);
|
||||
}
|
||||
}
|
||||
|
||||
#define aesenc_step_avx2(t_key)\
|
||||
__ aesenc(xmm1, t_key);\
|
||||
__ aesenc(xmm2, t_key);\
|
||||
__ aesenc(xmm3, t_key);\
|
||||
__ aesenc(xmm4, t_key);\
|
||||
__ aesenc(xmm5, t_key);\
|
||||
__ aesenc(xmm6, t_key);\
|
||||
__ aesenc(xmm7, t_key);\
|
||||
__ aesenc(xmm8, t_key);\
|
||||
|
||||
#define ghash_step_avx2(ghdata, hkey) \
|
||||
__ vpclmulqdq(xmm11, ghdata, hkey, 0x11);\
|
||||
__ vpxor(xmm12, xmm12, xmm11, Assembler::AVX_128bit);\
|
||||
__ vpclmulqdq(xmm11, ghdata, hkey, 0x00);\
|
||||
__ vpxor(xmm15, xmm15, xmm11, Assembler::AVX_128bit);\
|
||||
__ vpclmulqdq(xmm11, ghdata, hkey, 0x01);\
|
||||
__ vpxor(xmm14, xmm14, xmm11, Assembler::AVX_128bit);\
|
||||
__ vpclmulqdq(xmm11, ghdata, hkey, 0x10);\
|
||||
__ vpxor(xmm14, xmm14, xmm11, Assembler::AVX_128bit);\
|
||||
|
||||
//Encrypts and hashes 8 blocks in an interleaved fashion.
|
||||
//Inputs:
|
||||
//key - key for aes operations
|
||||
//subkeyHtbl - table containing H constants
|
||||
//ctr_blockx - counter for aes operations
|
||||
//in - input buffer
|
||||
//out - output buffer
|
||||
//ct - ciphertext buffer
|
||||
//pos - holds the length processed in this method
|
||||
//in_order - boolean that indicates if incrementing counter without shuffling is needed
|
||||
//rounds - number of aes rounds calculated based on key length
|
||||
//xmm1-xmm8 - holds encrypted counter values
|
||||
//Outputs:
|
||||
//xmm1-xmm8 - updated encrypted counter values
|
||||
//ctr_blockx - updated counter value
|
||||
//out - updated output buffer
|
||||
//Temp registers: xmm0, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15, rbx
|
||||
void StubGenerator::ghash8_encrypt8_parallel_avx2(Register key, Register subkeyHtbl, XMMRegister ctr_blockx, Register in,
|
||||
Register out, Register ct, Register pos, bool in_order, Register rounds,
|
||||
XMMRegister xmm1, XMMRegister xmm2, XMMRegister xmm3, XMMRegister xmm4,
|
||||
XMMRegister xmm5, XMMRegister xmm6, XMMRegister xmm7, XMMRegister xmm8) {
|
||||
const XMMRegister t1 = xmm0;
|
||||
const XMMRegister t2 = xmm10;
|
||||
const XMMRegister t3 = xmm11;
|
||||
const XMMRegister t4 = xmm12;
|
||||
const XMMRegister t5 = xmm13;
|
||||
const XMMRegister t6 = xmm14;
|
||||
const XMMRegister t7 = xmm15;
|
||||
Label skip_reload, last_aes_rnd, aes_192, aes_256;
|
||||
|
||||
__ movdqu(t2, xmm1);
|
||||
for (int i = 0; i <= 6; i++) {
|
||||
__ movdqu(Address(rsp, 16 * i), as_XMMRegister(i + 2));
|
||||
}
|
||||
|
||||
if (in_order) {
|
||||
__ vpaddd(xmm1, ctr_blockx, ExternalAddress(counter_mask_linc1_addr()), Assembler::AVX_128bit, rbx /*rscratch*/); //Increment counter by 1
|
||||
__ movdqu(t5, ExternalAddress(counter_mask_linc2_addr()), rbx /*rscratch*/);
|
||||
__ vpaddd(xmm2, ctr_blockx, t5, Assembler::AVX_128bit);
|
||||
for (int rnum = 1; rnum <= 6; rnum++) {
|
||||
__ vpaddd(as_XMMRegister(rnum + 2), as_XMMRegister(rnum), t5, Assembler::AVX_128bit);
|
||||
}
|
||||
__ movdqu(ctr_blockx, xmm8);
|
||||
|
||||
__ movdqu(t5, ExternalAddress(counter_shuffle_mask_addr()), rbx /*rscratch*/);
|
||||
for (int rnum = 1; rnum <= 8; rnum++) {
|
||||
__ vpshufb(as_XMMRegister(rnum), as_XMMRegister(rnum), t5, Assembler::AVX_128bit); //perform a 16Byte swap
|
||||
}
|
||||
} else {
|
||||
__ vpaddd(xmm1, ctr_blockx, ExternalAddress(counter_mask_linc1f_addr()), Assembler::AVX_128bit, rbx /*rscratch*/); //Increment counter by 1
|
||||
__ vmovdqu(t5, ExternalAddress(counter_mask_linc2f_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
__ vpaddd(xmm2, ctr_blockx, t5, Assembler::AVX_128bit);
|
||||
for (int rnum = 1; rnum <= 6; rnum++) {
|
||||
__ vpaddd(as_XMMRegister(rnum + 2), as_XMMRegister(rnum), t5, Assembler::AVX_128bit);
|
||||
}
|
||||
__ movdqu(ctr_blockx, xmm8);
|
||||
}
|
||||
|
||||
load_key(t1, key, 16 * 0, rbx /*rscratch*/);
|
||||
for (int rnum = 1; rnum <= 8; rnum++) {
|
||||
__ vpxor(as_XMMRegister(rnum), as_XMMRegister(rnum), t1, Assembler::AVX_128bit);
|
||||
}
|
||||
|
||||
load_key(t1, key, 16 * 1, rbx /*rscratch*/);
|
||||
aesenc_step_avx2(t1);
|
||||
|
||||
load_key(t1, key, 16 * 2, rbx /*rscratch*/);
|
||||
aesenc_step_avx2(t1);
|
||||
|
||||
__ movdqu(t5, (Address(subkeyHtbl, 8 * 16)));
|
||||
__ vpclmulqdq(t4, t2, t5, 0x11); //t4 = a1*b1
|
||||
__ vpclmulqdq(t7, t2, t5, 0x00); //t7 = a0*b0
|
||||
__ vpclmulqdq(t6, t2, t5, 0x01); //t6 = a1*b0
|
||||
__ vpclmulqdq(t5, t2, t5, 0x10); //t5 = a0*b1
|
||||
__ vpxor(t6, t6, t5, Assembler::AVX_128bit);
|
||||
|
||||
for (int i = 3, j = 0; i <= 8; i++, j++) {
|
||||
load_key(t1, key, 16 * i, rbx /*rscratch*/);
|
||||
aesenc_step_avx2(t1);
|
||||
__ movdqu(t1, Address(rsp, 16 * j));
|
||||
__ movdqu(t5, (Address(subkeyHtbl, (7 - j) * 16)));
|
||||
ghash_step_avx2(t1, t5);
|
||||
}
|
||||
|
||||
load_key(t1, key, 16 * 9, rbx /*rscratch*/);
|
||||
aesenc_step_avx2(t1);
|
||||
|
||||
__ movdqu(t1, Address(rsp, 16 * 6));
|
||||
__ movdqu(t5, (Address(subkeyHtbl, 1 * 16)));
|
||||
|
||||
__ vpclmulqdq(t3, t1, t5, 0x00);
|
||||
__ vpxor(t7, t7, t3, Assembler::AVX_128bit);
|
||||
|
||||
__ vpclmulqdq(t3, t1, t5, 0x01);
|
||||
__ vpxor(t6, t6, t3, Assembler::AVX_128bit);
|
||||
|
||||
__ vpclmulqdq(t3, t1, t5, 0x10);
|
||||
__ vpxor(t6, t6, t3, Assembler::AVX_128bit);
|
||||
|
||||
__ vpclmulqdq(t3, t1, t5, 0x11);
|
||||
__ vpxor(t1, t4, t3, Assembler::AVX_128bit);
|
||||
|
||||
__ vpslldq(t3, t6, 8, Assembler::AVX_128bit); //shift-L t3 2 DWs
|
||||
__ vpsrldq(t6, t6, 8, Assembler::AVX_128bit); //shift-R t2 2 DWs
|
||||
__ vpxor(t7, t7, t3, Assembler::AVX_128bit);
|
||||
__ vpxor(t1, t1, t6, Assembler::AVX_128bit); // accumulate the results in t1:t7
|
||||
|
||||
load_key(t5, key, 16 * 10, rbx /*rscratch*/);
|
||||
__ cmpl(rounds, 52);
|
||||
__ jcc(Assembler::less, last_aes_rnd);
|
||||
|
||||
__ bind(aes_192);
|
||||
aesenc_step_avx2(t5);
|
||||
load_key(t5, key, 16 * 11, rbx /*rscratch*/);
|
||||
aesenc_step_avx2(t5);
|
||||
load_key(t5, key, 16 * 12, rbx /*rscratch*/);
|
||||
__ cmpl(rounds, 60);
|
||||
__ jcc(Assembler::less, last_aes_rnd);
|
||||
|
||||
__ bind(aes_256);
|
||||
aesenc_step_avx2(t5);
|
||||
load_key(t5, key, 16 * 13, rbx /*rscratch*/);
|
||||
aesenc_step_avx2(t5);
|
||||
load_key(t5, key, 16 * 14, rbx /*rscratch*/);
|
||||
__ bind(last_aes_rnd);
|
||||
for (int rnum = 1; rnum <= 8; rnum++) {
|
||||
__ aesenclast(as_XMMRegister(rnum), t5);
|
||||
}
|
||||
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
__ movdqu(t2, Address(in, pos, Address::times_1, 16 * i));
|
||||
__ vpxor(as_XMMRegister(i + 1), as_XMMRegister(i + 1), t2, Assembler::AVX_128bit);
|
||||
}
|
||||
|
||||
//first phase of the reduction
|
||||
__ vmovdqu(t3, ExternalAddress(ghash_polynomial_reduction_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
|
||||
__ vpclmulqdq(t2, t3, t7, 0x01);
|
||||
__ vpslldq(t2, t2, 8, Assembler::AVX_128bit); //shift-L xmm2 2 DWs
|
||||
|
||||
__ vpxor(t7, t7, t2, Assembler::AVX_128bit); //first phase of the reduction complete
|
||||
|
||||
//Write to the Ciphertext buffer
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
__ movdqu(Address(out, pos, Address::times_1, 16 * i), as_XMMRegister(i + 1));
|
||||
}
|
||||
|
||||
__ cmpptr(ct, out);
|
||||
__ jcc(Assembler::equal, skip_reload);
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
__ movdqu(as_XMMRegister(i + 1), Address(in, pos, Address::times_1, 16 * i));
|
||||
}
|
||||
|
||||
__ bind(skip_reload);
|
||||
//second phase of the reduction
|
||||
__ vpclmulqdq(t2, t3, t7, 0x00);
|
||||
__ vpsrldq(t2, t2, 4, Assembler::AVX_128bit); //shift-R t2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R)
|
||||
|
||||
__ vpclmulqdq(t4, t3, t7, 0x10);
|
||||
__ vpslldq(t4, t4, 4, Assembler::AVX_128bit); //shift-L t4 1 DW (Shift-L 1-DW to obtain result with no shifts)
|
||||
__ vpxor(t4, t4, t2, Assembler::AVX_128bit); //second phase of the reduction complete
|
||||
__ vpxor(t1, t1, t4, Assembler::AVX_128bit); //the result is in t1
|
||||
|
||||
//perform a 16Byte swap
|
||||
__ movdqu(t7, ExternalAddress(counter_shuffle_mask_addr()), rbx /*rscratch*/);
|
||||
for (int rnum = 1; rnum <= 8; rnum++) {
|
||||
__ vpshufb(as_XMMRegister(rnum), as_XMMRegister(rnum), t7, Assembler::AVX_128bit);
|
||||
}
|
||||
__ vpxor(xmm1, xmm1, t1, Assembler::AVX_128bit);
|
||||
}
|
||||
|
||||
//GHASH the last 8 ciphertext blocks.
|
||||
//Input:
|
||||
//subkeyHtbl - table containing H constants
|
||||
//Output:
|
||||
//xmm14 - calculated aad hash
|
||||
//Temp registers: xmm0, xmm10, xmm11, xmm12, xmm13, xmm15, rbx
|
||||
void StubGenerator::ghash_last_8_avx2(Register subkeyHtbl) {
|
||||
const XMMRegister t1 = xmm0;
|
||||
const XMMRegister t2 = xmm10;
|
||||
const XMMRegister t3 = xmm11;
|
||||
const XMMRegister t4 = xmm12;
|
||||
const XMMRegister t5 = xmm13;
|
||||
const XMMRegister t6 = xmm14;
|
||||
const XMMRegister t7 = xmm15;
|
||||
|
||||
//Karatsuba Method
|
||||
__ movdqu(t5, Address(subkeyHtbl, 8 * 16));
|
||||
|
||||
__ vpshufd(t2, xmm1, 78, Assembler::AVX_128bit);
|
||||
__ vpshufd(t3, t5, 78, Assembler::AVX_128bit);
|
||||
__ vpxor(t2, t2, xmm1, Assembler::AVX_128bit);
|
||||
__ vpxor(t3, t3, t5, Assembler::AVX_128bit);
|
||||
|
||||
__ vpclmulqdq(t6, xmm1, t5, 0x11);
|
||||
__ vpclmulqdq(t7, xmm1, t5, 0x00);
|
||||
|
||||
__ vpclmulqdq(xmm1, t2, t3, 0x00);
|
||||
|
||||
for (int i = 7, rnum = 2; rnum <= 8; i--, rnum++) {
|
||||
__ movdqu(t5, Address(subkeyHtbl, i * 16));
|
||||
__ vpshufd(t2, as_XMMRegister(rnum), 78, Assembler::AVX_128bit);
|
||||
__ vpshufd(t3, t5, 78, Assembler::AVX_128bit);
|
||||
__ vpxor(t2, t2, as_XMMRegister(rnum), Assembler::AVX_128bit);
|
||||
__ vpxor(t3, t3, t5, Assembler::AVX_128bit);
|
||||
__ vpclmulqdq(t4, as_XMMRegister(rnum), t5, 0x11);
|
||||
__ vpxor(t6, t6, t4, Assembler::AVX_128bit);
|
||||
__ vpclmulqdq(t4, as_XMMRegister(rnum), t5, 0x00);
|
||||
__ vpxor(t7, t7, t4, Assembler::AVX_128bit);
|
||||
__ vpclmulqdq(t2, t2, t3, 0x00);
|
||||
__ vpxor(xmm1, xmm1, t2, Assembler::AVX_128bit);
|
||||
}
|
||||
|
||||
__ vpxor(xmm1, xmm1, t6, Assembler::AVX_128bit);
|
||||
__ vpxor(t2, xmm1, t7, Assembler::AVX_128bit);
|
||||
|
||||
__ vpslldq(t4, t2, 8, Assembler::AVX_128bit);
|
||||
__ vpsrldq(t2, t2, 8, Assembler::AVX_128bit);
|
||||
|
||||
__ vpxor(t7, t7, t4, Assembler::AVX_128bit);
|
||||
__ vpxor(t6, t6, t2, Assembler::AVX_128bit); //<t6:t7> holds the result of the accumulated carry-less multiplications
|
||||
|
||||
//first phase of the reduction
|
||||
__ movdqu(t3, ExternalAddress(ghash_polynomial_reduction_addr()), rbx /*rscratch*/);
|
||||
|
||||
__ vpclmulqdq(t2, t3, t7, 0x01);
|
||||
__ vpslldq(t2, t2, 8, Assembler::AVX_128bit); // shift-L t2 2 DWs
|
||||
|
||||
__ vpxor(t7, t7, t2, Assembler::AVX_128bit);//first phase of the reduction complete
|
||||
|
||||
//second phase of the reduction
|
||||
__ vpclmulqdq(t2, t3, t7, 0x00);
|
||||
__ vpsrldq(t2, t2, 4, Assembler::AVX_128bit); //shift-R t2 1 DW (Shift-R only 1-DW to obtain 2-DWs shift-R)
|
||||
|
||||
__ vpclmulqdq(t4, t3, t7, 0x10);
|
||||
__ vpslldq(t4, t4, 4, Assembler::AVX_128bit); //shift-L t4 1 DW (Shift-L 1-DW to obtain result with no shifts)
|
||||
__ vpxor(t4, t4, t2, Assembler::AVX_128bit); //second phase of the reduction complete
|
||||
__ vpxor(t6, t6, t4, Assembler::AVX_128bit); //the result is in t6
|
||||
}
|
||||
|
||||
//Encrypt initial number of 8 blocks
|
||||
//Inputs:
|
||||
//ctr - counter for aes operations
|
||||
//rounds - number of aes rounds calculated based on key length
|
||||
//key - key for aes operations
|
||||
//len - input length to be processed
|
||||
//in - input buffer
|
||||
//out - output buffer
|
||||
//ct - ciphertext buffer
|
||||
//aad_hashx - input aad hash
|
||||
//pos - holds the length processed in this method
|
||||
//Outputs:
|
||||
//xmm1-xmm8 - holds updated encrypted counter values
|
||||
//ctr - updated counter value
|
||||
//pos - updated position
|
||||
//len - updated length
|
||||
//out - updated output buffer
|
||||
//Temp registers: xmm0, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
|
||||
void StubGenerator::initial_blocks_avx2(XMMRegister ctr, Register rounds, Register key, Register len, Register in,
|
||||
Register out, Register ct, XMMRegister aad_hashx, Register pos) {
|
||||
const XMMRegister t1 = xmm12;
|
||||
const XMMRegister t2 = xmm13;
|
||||
const XMMRegister t3 = xmm14;
|
||||
const XMMRegister t4 = xmm15;
|
||||
const XMMRegister t5 = xmm11;
|
||||
const XMMRegister t6 = xmm10;
|
||||
const XMMRegister t_key = xmm0;
|
||||
|
||||
Label skip_reload, last_aes_rnd, aes_192, aes_256;
|
||||
//Move AAD_HASH to temp reg t3
|
||||
__ movdqu(t3, aad_hashx);
|
||||
//Prepare 8 counter blocks and perform rounds of AES cipher on
|
||||
//them, load plain/cipher text and store cipher/plain text.
|
||||
__ movdqu(xmm1, ctr);
|
||||
__ movdqu(t5, ExternalAddress(counter_mask_linc1_addr()), rbx /*rscratch*/);
|
||||
__ movdqu(t6, ExternalAddress(counter_mask_linc2_addr()), rbx /*rscratch*/ );
|
||||
__ vpaddd(xmm2, xmm1, t5, Assembler::AVX_128bit);
|
||||
for (int rnum = 1; rnum <= 6; rnum++) {
|
||||
__ vpaddd(as_XMMRegister(rnum + 2), as_XMMRegister(rnum), t6, Assembler::AVX_128bit);
|
||||
}
|
||||
__ movdqu(ctr, xmm8);
|
||||
|
||||
__ movdqu(t5, ExternalAddress(counter_shuffle_mask_addr()), rbx /*rscratch*/);
|
||||
for (int rnum = 1; rnum <= 8; rnum++) {
|
||||
__ vpshufb(as_XMMRegister(rnum), as_XMMRegister(rnum), t5, Assembler::AVX_128bit); //perform a 16Byte swap
|
||||
}
|
||||
|
||||
load_key(t_key, key, 16 * 0, rbx /*rscratch*/);
|
||||
for (int rnum = 1; rnum <= 8; rnum++) {
|
||||
__ vpxor(as_XMMRegister(rnum), as_XMMRegister(rnum), t_key, Assembler::AVX_128bit);
|
||||
}
|
||||
|
||||
for (int i = 1; i <= 9; i++) {
|
||||
load_key(t_key, key, 16 * i, rbx /*rscratch*/);
|
||||
aesenc_step_avx2(t_key);
|
||||
}
|
||||
|
||||
load_key(t_key, key, 16 * 10, rbx /*rscratch*/);
|
||||
__ cmpl(rounds, 52);
|
||||
__ jcc(Assembler::less, last_aes_rnd);
|
||||
|
||||
__ bind(aes_192);
|
||||
aesenc_step_avx2(t_key);
|
||||
load_key(t_key, key, 16 * 11, rbx /*rscratch*/);
|
||||
aesenc_step_avx2(t_key);
|
||||
load_key(t_key, key, 16 * 12, rbx /*rscratch*/);
|
||||
__ cmpl(rounds, 60);
|
||||
__ jcc(Assembler::less, last_aes_rnd);
|
||||
|
||||
__ bind(aes_256);
|
||||
aesenc_step_avx2(t_key);
|
||||
load_key(t_key, key, 16 * 13, rbx /*rscratch*/);
|
||||
aesenc_step_avx2(t_key);
|
||||
load_key(t_key, key, 16 * 14, rbx /*rscratch*/);
|
||||
|
||||
__ bind(last_aes_rnd);
|
||||
for (int rnum = 1; rnum <= 8; rnum++) {
|
||||
__ aesenclast(as_XMMRegister(rnum), t_key);
|
||||
}
|
||||
|
||||
//XOR and store data
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
__ movdqu(t1, Address(in, pos, Address::times_1, 16 * i));
|
||||
__ vpxor(as_XMMRegister(i + 1), as_XMMRegister(i + 1), t1, Assembler::AVX_128bit);
|
||||
__ movdqu(Address(out, pos, Address::times_1, 16 * i), as_XMMRegister(i + 1));
|
||||
}
|
||||
|
||||
__ cmpptr(ct, out);
|
||||
__ jcc(Assembler::equal, skip_reload);
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
__ movdqu(as_XMMRegister(i + 1), Address(in, pos, Address::times_1, 16 * i));
|
||||
}
|
||||
|
||||
__ bind(skip_reload);
|
||||
//Update len with the number of blocks processed
|
||||
__ subl(len, 128);
|
||||
__ addl(pos, 128);
|
||||
|
||||
__ movdqu(t4, ExternalAddress(counter_shuffle_mask_addr()), rbx /*rscratch*/);
|
||||
for (int rnum = 1; rnum <= 8; rnum++) {
|
||||
__ vpshufb(as_XMMRegister(rnum), as_XMMRegister(rnum), t4, Assembler::AVX_128bit);
|
||||
}
|
||||
// Combine GHASHed value with the corresponding ciphertext
|
||||
__ vpxor(xmm1, xmm1, t3, Assembler::AVX_128bit);
|
||||
}
|
||||
|
||||
//AES-GCM interleaved implementation
|
||||
//Inputs:
|
||||
//in - input buffer
|
||||
//len- message length to be processed
|
||||
//ct - cipher text buffer
|
||||
//out - output buffer
|
||||
//key - key for aes operations
|
||||
//state - address of aad hash for ghash computation
|
||||
//subkeyHtbl- table consisting of H constants
|
||||
//counter - address of counter for aes operations
|
||||
//Output:
|
||||
//(counter) - updated in memory counter value
|
||||
//(state) - updated in memory aad hash
|
||||
//rax - length processed
|
||||
//(out) - output buffer updated
|
||||
//len - updated length
|
||||
//Temp registers: xmm0-xmm15, r10, r15, rbx
|
||||
void StubGenerator::aesgcm_avx2(Register in, Register len, Register ct, Register out, Register key,
|
||||
Register state, Register subkeyHtbl, Register counter) {
|
||||
const Register pos = rax;
|
||||
const Register rounds = r10;
|
||||
const XMMRegister ctr_blockx = xmm9;
|
||||
const XMMRegister aad_hashx = xmm8;
|
||||
Label encrypt_done, encrypt_by_8_new, encrypt_by_8;
|
||||
|
||||
//This routine should be called only for message sizes of 128 bytes or more.
|
||||
//Macro flow:
|
||||
//process 8 16 byte blocks in initial_num_blocks.
|
||||
//process 8 16 byte blocks at a time until all are done 'encrypt_by_8_new followed by ghash_last_8'
|
||||
__ xorl(pos, pos);
|
||||
|
||||
//Generate 8 constants for htbl
|
||||
generateHtbl_8_block_avx2(subkeyHtbl);
|
||||
|
||||
//Compute #rounds for AES based on the length of the key array
|
||||
__ movl(rounds, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
|
||||
|
||||
//Load and shuffle state and counter values
|
||||
__ movdqu(ctr_blockx, Address(counter, 0));
|
||||
__ movdqu(aad_hashx, Address(state, 0));
|
||||
__ vpshufb(ctr_blockx, ctr_blockx, ExternalAddress(counter_shuffle_mask_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
__ vpshufb(aad_hashx, aad_hashx, ExternalAddress(ghash_long_swap_mask_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
|
||||
initial_blocks_avx2(ctr_blockx, rounds, key, len, in, out, ct, aad_hashx, pos);
|
||||
|
||||
//We need at least 128 bytes to proceed further.
|
||||
__ cmpl(len, 128);
|
||||
__ jcc(Assembler::less, encrypt_done);
|
||||
|
||||
//in_order vs. out_order is an optimization to increment the counter without shuffling
|
||||
//it back into little endian. r15d keeps track of when we need to increment in order so
|
||||
//that the carry is handled correctly.
|
||||
__ movdl(r15, ctr_blockx);
|
||||
__ andl(r15, 255);
|
||||
__ vpshufb(ctr_blockx, ctr_blockx, ExternalAddress(counter_shuffle_mask_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
|
||||
__ bind(encrypt_by_8_new);
|
||||
__ cmpl(r15, 255 - 8);
|
||||
__ jcc(Assembler::greater, encrypt_by_8);
|
||||
|
||||
__ addb(r15, 8);
|
||||
ghash8_encrypt8_parallel_avx2(key, subkeyHtbl, ctr_blockx, in, out, ct, pos, false, rounds,
|
||||
xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8);
|
||||
__ addl(pos, 128);
|
||||
__ subl(len, 128);
|
||||
__ cmpl(len, 128);
|
||||
__ jcc(Assembler::greaterEqual, encrypt_by_8_new);
|
||||
|
||||
__ vpshufb(ctr_blockx, ctr_blockx, ExternalAddress(counter_shuffle_mask_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
__ jmp(encrypt_done);
|
||||
|
||||
__ bind(encrypt_by_8);
|
||||
__ vpshufb(ctr_blockx, ctr_blockx, ExternalAddress(counter_shuffle_mask_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
|
||||
__ addb(r15, 8);
|
||||
ghash8_encrypt8_parallel_avx2(key, subkeyHtbl, ctr_blockx, in, out, ct, pos, true, rounds,
|
||||
xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8);
|
||||
|
||||
__ vpshufb(ctr_blockx, ctr_blockx, ExternalAddress(counter_shuffle_mask_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
__ addl(pos, 128);
|
||||
__ subl(len, 128);
|
||||
__ cmpl(len, 128);
|
||||
__ jcc(Assembler::greaterEqual, encrypt_by_8_new);
|
||||
__ vpshufb(ctr_blockx, ctr_blockx, ExternalAddress(counter_shuffle_mask_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
|
||||
__ bind(encrypt_done);
|
||||
ghash_last_8_avx2(subkeyHtbl);
|
||||
|
||||
__ vpaddd(ctr_blockx, ctr_blockx, ExternalAddress(counter_mask_linc1_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
__ vpshufb(ctr_blockx, ctr_blockx, ExternalAddress(counter_shuffle_mask_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
__ movdqu(Address(counter, 0), ctr_blockx); //current_counter = xmm9
|
||||
__ vpshufb(xmm14, xmm14, ExternalAddress(ghash_long_swap_mask_addr()), Assembler::AVX_128bit, rbx /*rscratch*/);
|
||||
__ movdqu(Address(state, 0), xmm14); //aad hash = xmm14
|
||||
//Xor out round keys
|
||||
__ vpxor(xmm0, xmm0, xmm0, Assembler::AVX_128bit);
|
||||
__ vpxor(xmm13, xmm13, xmm13, Assembler::AVX_128bit);
|
||||
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
@@ -37,7 +37,7 @@ enum platform_dependent_constants {
|
||||
_continuation_stubs_code_size = 1000 LP64_ONLY(+1000),
|
||||
// AVX512 intrinsics add more code in 64-bit VM,
|
||||
// Windows have more code to save/restore registers
|
||||
_compiler_stubs_code_size = 20000 LP64_ONLY(+30000) WINDOWS_ONLY(+2000),
|
||||
_compiler_stubs_code_size = 20000 LP64_ONLY(+32000) WINDOWS_ONLY(+2000),
|
||||
_final_stubs_code_size = 10000 LP64_ONLY(+20000) WINDOWS_ONLY(+2000) ZGC_ONLY(+20000)
|
||||
};
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
|
||||
__ block_comment("} restore_callee_saved_regs ");
|
||||
}
|
||||
|
||||
static const int upcall_stub_code_base_size = 2048;
|
||||
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,
|
||||
@@ -272,6 +272,7 @@ 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);
|
||||
@@ -288,9 +289,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
__ block_comment("} argument shuffle");
|
||||
|
||||
__ block_comment("{ receiver ");
|
||||
__ movptr(rscratch1, (intptr_t)receiver);
|
||||
__ resolve_jobject(rscratch1, r15_thread, rscratch2);
|
||||
__ movptr(j_rarg0, rscratch1);
|
||||
__ get_vm_result(j_rarg0, r15_thread);
|
||||
__ block_comment("} receiver ");
|
||||
|
||||
__ mov_metadata(rbx, entry);
|
||||
@@ -361,27 +360,8 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__ block_comment("{ exception handler");
|
||||
|
||||
intptr_t exception_handler_offset = __ pc() - start;
|
||||
|
||||
// TODO: this is always the same, can we bypass and call handle_uncaught_exception directly?
|
||||
|
||||
// native caller has no idea how to handle exceptions
|
||||
// we just crash here. Up to callee to catch exceptions.
|
||||
__ verify_oop(rax);
|
||||
__ vzeroupper();
|
||||
__ mov(c_rarg0, rax);
|
||||
__ andptr(rsp, -StackAlignmentInBytes); // align stack as required by ABI
|
||||
__ subptr(rsp, frame::arg_reg_save_area_bytes); // windows (not really needed)
|
||||
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, UpcallLinker::handle_uncaught_exception)));
|
||||
__ should_not_reach_here();
|
||||
|
||||
__ block_comment("} exception handler");
|
||||
|
||||
_masm->flush();
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
stringStream ss;
|
||||
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
|
||||
@@ -395,7 +375,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
|
||||
UpcallStub* blob
|
||||
= UpcallStub::create(name,
|
||||
&buffer,
|
||||
exception_handler_offset,
|
||||
receiver,
|
||||
in_ByteSize(frame_data_offset));
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ register %{
|
||||
//
|
||||
// Linux ABI: No register preserved across function calls
|
||||
// XMM0-XMM7 might hold parameters
|
||||
// Windows ABI: XMM6-XMM31 preserved across function calls
|
||||
// Windows ABI: XMM6-XMM15 preserved across function calls
|
||||
// XMM0-XMM3 might hold parameters
|
||||
|
||||
reg_def XMM0 ( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg());
|
||||
|
||||
@@ -225,6 +225,7 @@ static bool reload_table() {
|
||||
lm->path = g_stringlist.add(ldi->ldinfo_filename);
|
||||
if (!lm->path) {
|
||||
trcVerbose("OOM.");
|
||||
free(lm);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -246,6 +247,7 @@ static bool reload_table() {
|
||||
lm->member = g_stringlist.add(p_mbr_name);
|
||||
if (!lm->member) {
|
||||
trcVerbose("OOM.");
|
||||
free(lm);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -769,7 +769,8 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
|
||||
// Init thread attributes.
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
int rslt = pthread_attr_init(&attr);
|
||||
guarantee(rslt == 0, "pthread_attr_init has to return 0");
|
||||
guarantee(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "???");
|
||||
|
||||
// Make sure we run in 1:1 kernel-user-thread mode.
|
||||
@@ -803,6 +804,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
stack_size / K);
|
||||
thread->set_osthread(nullptr);
|
||||
delete osthread;
|
||||
pthread_attr_destroy(&attr);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "nmt/memTracker.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include <sys/mman.h>
|
||||
|
||||
void SafepointMechanism::pd_initialize() {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "nmt/memTracker.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "os_bsd.inline.hpp"
|
||||
#include "os_posix.inline.hpp"
|
||||
@@ -60,7 +61,6 @@
|
||||
#include "runtime/threads.hpp"
|
||||
#include "runtime/timer.hpp"
|
||||
#include "services/attachListener.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include "services/runtimeService.hpp"
|
||||
#include "signals_posix.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
@@ -202,11 +202,13 @@ static char cpu_arch[] = "ppc";
|
||||
#error Add appropriate cpu_arch setting
|
||||
#endif
|
||||
|
||||
// Compiler variant
|
||||
#ifdef COMPILER2
|
||||
#define COMPILER_VARIANT "server"
|
||||
// JVM variant
|
||||
#if defined(ZERO)
|
||||
#define JVM_VARIANT "zero"
|
||||
#elif defined(COMPILER2)
|
||||
#define JVM_VARIANT "server"
|
||||
#else
|
||||
#define COMPILER_VARIANT "client"
|
||||
#define JVM_VARIANT "client"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1501,10 +1503,10 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
snprintf(jrelib_p, buflen-len, "/lib");
|
||||
}
|
||||
|
||||
// Add the appropriate client or server subdir
|
||||
// Add the appropriate JVM variant subdir
|
||||
len = strlen(buf);
|
||||
jrelib_p = buf + len;
|
||||
snprintf(jrelib_p, buflen-len, "/%s", COMPILER_VARIANT);
|
||||
snprintf(jrelib_p, buflen-len, "/%s", JVM_VARIANT);
|
||||
if (0 != access(buf, F_OK)) {
|
||||
snprintf(jrelib_p, buflen-len, "%s", "");
|
||||
}
|
||||
|
||||
@@ -44,18 +44,12 @@
|
||||
product(bool, UseLinuxPosixThreadCPUClocks, true, \
|
||||
"enable fast Linux Posix clocks where available") \
|
||||
\
|
||||
product(bool, UseHugeTLBFS, false, \
|
||||
"Use MAP_HUGETLB for large pages") \
|
||||
\
|
||||
product(bool, UseTransparentHugePages, false, \
|
||||
"Use MADV_HUGEPAGE for large pages") \
|
||||
\
|
||||
product(bool, LoadExecStackDllInVMThread, true, \
|
||||
"Load DLLs with executable-stack attribute in the VM Thread") \
|
||||
\
|
||||
product(bool, UseSHM, false, \
|
||||
"Use SYSV shared memory for large pages") \
|
||||
\
|
||||
product(bool, UseContainerSupport, true, \
|
||||
"Enable detection and runtime container configuration support") \
|
||||
\
|
||||
|
||||
@@ -36,10 +36,11 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "nmt/memTracker.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "osContainer_linux.hpp"
|
||||
#include "os_linux.inline.hpp"
|
||||
#include "os_posix.inline.hpp"
|
||||
#include "osContainer_linux.hpp"
|
||||
#include "prims/jniFastGetField.hpp"
|
||||
#include "prims/jvm_misc.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
@@ -64,19 +65,18 @@
|
||||
#include "runtime/threadSMR.hpp"
|
||||
#include "runtime/timer.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "signals_posix.hpp"
|
||||
#include "semaphore_posix.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include "services/runtimeService.hpp"
|
||||
#include "signals_posix.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/checkedCast.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/decoder.hpp"
|
||||
#include "utilities/defaultStream.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
#include "utilities/elfFile.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
#include "utilities/vmError.hpp"
|
||||
@@ -111,7 +111,6 @@
|
||||
# include <syscall.h>
|
||||
# include <sys/sysinfo.h>
|
||||
# include <sys/ipc.h>
|
||||
# include <sys/shm.h>
|
||||
# include <link.h>
|
||||
# include <stdint.h>
|
||||
# include <inttypes.h>
|
||||
@@ -912,7 +911,12 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
|
||||
// init thread attributes
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
int rslt = pthread_attr_init(&attr);
|
||||
if (rslt != 0) {
|
||||
thread->set_osthread(nullptr);
|
||||
delete osthread;
|
||||
return false;
|
||||
}
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
// Calculate stack size if it's not specified by caller.
|
||||
@@ -961,6 +965,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
stack_size / K);
|
||||
thread->set_osthread(nullptr);
|
||||
delete osthread;
|
||||
pthread_attr_destroy(&attr);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2840,7 +2845,7 @@ void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
|
||||
#define MAP_FIXED_NOREPLACE MAP_FIXED_NOREPLACE_value
|
||||
#else
|
||||
// Sanity-check our assumed default value if we build with a new enough libc.
|
||||
static_assert(MAP_FIXED_NOREPLACE == MAP_FIXED_NOREPLACE_value);
|
||||
static_assert(MAP_FIXED_NOREPLACE == MAP_FIXED_NOREPLACE_value, "MAP_FIXED_NOREPLACE != MAP_FIXED_NOREPLACE_value");
|
||||
#endif
|
||||
|
||||
int os::Linux::commit_memory_impl(char* addr, size_t size,
|
||||
@@ -3607,14 +3612,17 @@ bool os::unguard_memory(char* addr, size_t size) {
|
||||
return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
|
||||
}
|
||||
|
||||
int os::Linux::hugetlbfs_page_size_flag(size_t page_size) {
|
||||
static int hugetlbfs_page_size_flag(size_t page_size) {
|
||||
if (page_size != HugePages::default_static_hugepage_size()) {
|
||||
return (exact_log2(page_size) << MAP_HUGE_SHIFT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
static bool hugetlbfs_sanity_check(size_t page_size) {
|
||||
const os::PageSizes page_sizes = HugePages::static_info().pagesizes();
|
||||
assert(page_sizes.contains(page_size), "Invalid page sizes passed");
|
||||
|
||||
// Include the page size flag to ensure we sanity check the correct page size.
|
||||
int flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB | hugetlbfs_page_size_flag(page_size);
|
||||
void *p = mmap(nullptr, page_size, PROT_READ|PROT_WRITE, flags, -1, 0);
|
||||
@@ -3628,9 +3636,9 @@ bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
"checking if smaller large page sizes are usable",
|
||||
byte_size_in_exact_unit(page_size),
|
||||
exact_unit_for_byte_size(page_size));
|
||||
for (size_t page_size_ = _page_sizes.next_smaller(page_size);
|
||||
page_size_ != os::vm_page_size();
|
||||
page_size_ = _page_sizes.next_smaller(page_size_)) {
|
||||
for (size_t page_size_ = page_sizes.next_smaller(page_size);
|
||||
page_size_ > os::vm_page_size();
|
||||
page_size_ = page_sizes.next_smaller(page_size_)) {
|
||||
flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_HUGETLB | hugetlbfs_page_size_flag(page_size_);
|
||||
p = mmap(nullptr, page_size_, PROT_READ|PROT_WRITE, flags, -1, 0);
|
||||
if (p != MAP_FAILED) {
|
||||
@@ -3644,37 +3652,9 @@ bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
}
|
||||
}
|
||||
|
||||
if (warn) {
|
||||
warning("HugeTLBFS is not configured or not supported by the operating system.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool os::Linux::shm_hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
// Try to create a large shared memory segment.
|
||||
int shmid = shmget(IPC_PRIVATE, page_size, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
|
||||
if (shmid == -1) {
|
||||
// Possible reasons for shmget failure:
|
||||
// 1. shmmax is too small for the request.
|
||||
// > check shmmax value: cat /proc/sys/kernel/shmmax
|
||||
// > increase shmmax value: echo "new_value" > /proc/sys/kernel/shmmax
|
||||
// 2. not enough large page memory.
|
||||
// > check available large pages: cat /proc/meminfo
|
||||
// > increase amount of large pages:
|
||||
// sysctl -w vm.nr_hugepages=new_value
|
||||
// > For more information regarding large pages please refer to:
|
||||
// https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
|
||||
if (warn) {
|
||||
warning("Large pages using UseSHM are not configured on this system.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Managed to create a segment, now delete it.
|
||||
shmctl(shmid, IPC_RMID, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// From the coredump_filter documentation:
|
||||
//
|
||||
// - (bit 0) anonymous private memory
|
||||
@@ -3722,56 +3702,13 @@ void warn_no_large_pages_configured() {
|
||||
}
|
||||
}
|
||||
|
||||
bool os::Linux::setup_large_page_type(size_t page_size) {
|
||||
if (FLAG_IS_DEFAULT(UseHugeTLBFS) &&
|
||||
FLAG_IS_DEFAULT(UseSHM) &&
|
||||
FLAG_IS_DEFAULT(UseTransparentHugePages)) {
|
||||
|
||||
// The type of large pages has not been specified by the user.
|
||||
|
||||
// Try UseHugeTLBFS and then UseSHM.
|
||||
UseHugeTLBFS = UseSHM = true;
|
||||
|
||||
// Don't try UseTransparentHugePages since there are known
|
||||
// performance issues with it turned on. This might change in the future.
|
||||
UseTransparentHugePages = false;
|
||||
}
|
||||
|
||||
if (UseTransparentHugePages) {
|
||||
UseHugeTLBFS = false;
|
||||
UseSHM = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (UseHugeTLBFS) {
|
||||
bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
|
||||
if (hugetlbfs_sanity_check(warn_on_failure, page_size)) {
|
||||
UseSHM = false;
|
||||
return true;
|
||||
}
|
||||
UseHugeTLBFS = false;
|
||||
}
|
||||
|
||||
if (UseSHM) {
|
||||
bool warn_on_failure = !FLAG_IS_DEFAULT(UseSHM);
|
||||
if (shm_hugetlbfs_sanity_check(warn_on_failure, page_size)) {
|
||||
return true;
|
||||
}
|
||||
UseSHM = false;
|
||||
}
|
||||
|
||||
warn_no_large_pages_configured();
|
||||
return false;
|
||||
}
|
||||
|
||||
struct LargePageInitializationLoggerMark {
|
||||
~LargePageInitializationLoggerMark() {
|
||||
LogTarget(Info, pagesize) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
if (UseLargePages) {
|
||||
ls.print_cr("UseLargePages=1, UseTransparentHugePages=%d, UseHugeTLBFS=%d, UseSHM=%d",
|
||||
UseTransparentHugePages, UseHugeTLBFS, UseSHM);
|
||||
ls.print_cr("UseLargePages=1, UseTransparentHugePages=%d", UseTransparentHugePages);
|
||||
ls.print("Large page support enabled. Usable page sizes: ");
|
||||
os::page_sizes().print_on(&ls);
|
||||
ls.print_cr(". Default large page size: " EXACTFMT ".", EXACTFMTARGS(os::large_page_size()));
|
||||
@@ -3805,19 +3742,14 @@ void os::large_page_init() {
|
||||
|
||||
// 1) Handle the case where we do not want to use huge pages
|
||||
if (!UseLargePages &&
|
||||
!UseTransparentHugePages &&
|
||||
!UseHugeTLBFS &&
|
||||
!UseSHM) {
|
||||
!UseTransparentHugePages) {
|
||||
// Not using large pages.
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FLAG_IS_DEFAULT(UseLargePages) && !UseLargePages) {
|
||||
// The user explicitly turned off large pages.
|
||||
// Ignore the rest of the large pages flags.
|
||||
UseTransparentHugePages = false;
|
||||
UseHugeTLBFS = false;
|
||||
UseSHM = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3826,12 +3758,12 @@ void os::large_page_init() {
|
||||
if (!FLAG_IS_DEFAULT(UseTransparentHugePages)) {
|
||||
log_warning(pagesize)("UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system.");
|
||||
}
|
||||
UseLargePages = UseTransparentHugePages = UseHugeTLBFS = UseSHM = false;
|
||||
UseLargePages = UseTransparentHugePages = false;
|
||||
return;
|
||||
}
|
||||
if (!UseTransparentHugePages && !HugePages::supports_static_hugepages()) {
|
||||
warn_no_large_pages_configured();
|
||||
UseLargePages = UseTransparentHugePages = UseHugeTLBFS = UseSHM = false;
|
||||
UseLargePages = UseTransparentHugePages = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3843,6 +3775,8 @@ void os::large_page_init() {
|
||||
_large_page_size = HugePages::thp_pagesize();
|
||||
_page_sizes.add(_large_page_size);
|
||||
_page_sizes.add(os::vm_page_size());
|
||||
// +UseTransparentHugePages implies +UseLargePages
|
||||
UseLargePages = true;
|
||||
|
||||
} else {
|
||||
|
||||
@@ -3855,6 +3789,8 @@ void os::large_page_init() {
|
||||
|
||||
// 3) Consistency check and post-processing
|
||||
|
||||
size_t large_page_size = 0;
|
||||
|
||||
// Check LargePageSizeInBytes matches an available page size and if so set _large_page_size
|
||||
// using LargePageSizeInBytes as the maximum allowed large page size. If LargePageSizeInBytes
|
||||
// doesn't match an available page size set _large_page_size to default_large_page_size
|
||||
@@ -3862,30 +3798,40 @@ void os::large_page_init() {
|
||||
if (FLAG_IS_DEFAULT(LargePageSizeInBytes) ||
|
||||
LargePageSizeInBytes == 0 ||
|
||||
LargePageSizeInBytes == default_large_page_size) {
|
||||
_large_page_size = default_large_page_size;
|
||||
large_page_size = default_large_page_size;
|
||||
log_info(pagesize)("Using the default large page size: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
byte_size_in_exact_unit(large_page_size),
|
||||
exact_unit_for_byte_size(large_page_size));
|
||||
} else {
|
||||
if (all_large_pages.contains(LargePageSizeInBytes)) {
|
||||
_large_page_size = LargePageSizeInBytes;
|
||||
large_page_size = LargePageSizeInBytes;
|
||||
log_info(pagesize)("Overriding default large page size (" SIZE_FORMAT "%s) "
|
||||
"using LargePageSizeInBytes: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(default_large_page_size),
|
||||
exact_unit_for_byte_size(default_large_page_size),
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
byte_size_in_exact_unit(large_page_size),
|
||||
exact_unit_for_byte_size(large_page_size));
|
||||
} else {
|
||||
_large_page_size = default_large_page_size;
|
||||
large_page_size = default_large_page_size;
|
||||
log_info(pagesize)("LargePageSizeInBytes is not a valid large page size (" SIZE_FORMAT "%s) "
|
||||
"using the default large page size: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(LargePageSizeInBytes),
|
||||
exact_unit_for_byte_size(LargePageSizeInBytes),
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
byte_size_in_exact_unit(large_page_size),
|
||||
exact_unit_for_byte_size(large_page_size));
|
||||
}
|
||||
}
|
||||
|
||||
// Do an additional sanity check to see if we can use the desired large page size
|
||||
if (!hugetlbfs_sanity_check(large_page_size)) {
|
||||
warn_no_large_pages_configured();
|
||||
UseLargePages = false;
|
||||
UseTransparentHugePages = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_large_page_size = large_page_size;
|
||||
|
||||
// Populate _page_sizes with large page sizes less than or equal to
|
||||
// _large_page_size.
|
||||
for (size_t page_size = _large_page_size; page_size != 0;
|
||||
@@ -3894,156 +3840,9 @@ void os::large_page_init() {
|
||||
}
|
||||
}
|
||||
|
||||
// Now determine the type of large pages to use:
|
||||
UseLargePages = os::Linux::setup_large_page_type(_large_page_size);
|
||||
|
||||
set_coredump_filter(LARGEPAGES_BIT);
|
||||
}
|
||||
|
||||
#ifndef SHM_HUGETLB
|
||||
#define SHM_HUGETLB 04000
|
||||
#endif
|
||||
|
||||
#define shm_warning_format(format, ...) \
|
||||
do { \
|
||||
if (UseLargePages && \
|
||||
(!FLAG_IS_DEFAULT(UseLargePages) || \
|
||||
!FLAG_IS_DEFAULT(UseSHM) || \
|
||||
!FLAG_IS_DEFAULT(LargePageSizeInBytes))) { \
|
||||
warning(format, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define shm_warning(str) shm_warning_format("%s", str)
|
||||
|
||||
#define shm_warning_with_errno(str) \
|
||||
do { \
|
||||
int err = errno; \
|
||||
shm_warning_format(str " (error = %d)", err); \
|
||||
} while (0)
|
||||
|
||||
static char* shmat_with_alignment(int shmid, size_t bytes, size_t alignment) {
|
||||
assert(is_aligned(bytes, alignment), "Must be divisible by the alignment");
|
||||
|
||||
if (!is_aligned(alignment, SHMLBA)) {
|
||||
assert(false, "Code below assumes that alignment is at least SHMLBA aligned");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// To ensure that we get 'alignment' aligned memory from shmat,
|
||||
// we pre-reserve aligned virtual memory and then attach to that.
|
||||
|
||||
char* pre_reserved_addr = anon_mmap_aligned(nullptr /* req_addr */, bytes, alignment);
|
||||
if (pre_reserved_addr == nullptr) {
|
||||
// Couldn't pre-reserve aligned memory.
|
||||
shm_warning("Failed to pre-reserve aligned memory for shmat.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// SHM_REMAP is needed to allow shmat to map over an existing mapping.
|
||||
char* addr = (char*)shmat(shmid, pre_reserved_addr, SHM_REMAP);
|
||||
|
||||
if ((intptr_t)addr == -1) {
|
||||
int err = errno;
|
||||
shm_warning_with_errno("Failed to attach shared memory.");
|
||||
|
||||
assert(err != EACCES, "Unexpected error");
|
||||
assert(err != EIDRM, "Unexpected error");
|
||||
assert(err != EINVAL, "Unexpected error");
|
||||
|
||||
// Since we don't know if the kernel unmapped the pre-reserved memory area
|
||||
// we can't unmap it, since that would potentially unmap memory that was
|
||||
// mapped from other threads.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static char* shmat_at_address(int shmid, char* req_addr) {
|
||||
if (!is_aligned(req_addr, SHMLBA)) {
|
||||
assert(false, "Requested address needs to be SHMLBA aligned");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
char* addr = (char*)shmat(shmid, req_addr, 0);
|
||||
|
||||
if ((intptr_t)addr == -1) {
|
||||
shm_warning_with_errno("Failed to attach shared memory.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static char* shmat_large_pages(int shmid, size_t bytes, size_t alignment, char* req_addr) {
|
||||
// If a req_addr has been provided, we assume that the caller has already aligned the address.
|
||||
if (req_addr != nullptr) {
|
||||
assert(is_aligned(req_addr, os::large_page_size()), "Must be divisible by the large page size");
|
||||
assert(is_aligned(req_addr, alignment), "Must be divisible by given alignment");
|
||||
return shmat_at_address(shmid, req_addr);
|
||||
}
|
||||
|
||||
// Since shmid has been setup with SHM_HUGETLB, shmat will automatically
|
||||
// return large page size aligned memory addresses when req_addr == nullptr.
|
||||
// However, if the alignment is larger than the large page size, we have
|
||||
// to manually ensure that the memory returned is 'alignment' aligned.
|
||||
if (alignment > os::large_page_size()) {
|
||||
assert(is_aligned(alignment, os::large_page_size()), "Must be divisible by the large page size");
|
||||
return shmat_with_alignment(shmid, bytes, alignment);
|
||||
} else {
|
||||
return shmat_at_address(shmid, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment,
|
||||
char* req_addr, bool exec) {
|
||||
// "exec" is passed in but not used. Creating the shared image for
|
||||
// the code cache doesn't have an SHM_X executable permission to check.
|
||||
assert(UseLargePages && UseSHM, "only for SHM large pages");
|
||||
assert(is_aligned(req_addr, os::large_page_size()), "Unaligned address");
|
||||
assert(is_aligned(req_addr, alignment), "Unaligned address");
|
||||
|
||||
if (!is_aligned(bytes, os::large_page_size())) {
|
||||
return nullptr; // Fallback to small pages.
|
||||
}
|
||||
|
||||
// Create a large shared memory region to attach to based on size.
|
||||
// Currently, size is the total size of the heap.
|
||||
int shmid = shmget(IPC_PRIVATE, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
|
||||
if (shmid == -1) {
|
||||
// Possible reasons for shmget failure:
|
||||
// 1. shmmax is too small for the request.
|
||||
// > check shmmax value: cat /proc/sys/kernel/shmmax
|
||||
// > increase shmmax value: echo "new_value" > /proc/sys/kernel/shmmax
|
||||
// 2. not enough large page memory.
|
||||
// > check available large pages: cat /proc/meminfo
|
||||
// > increase amount of large pages:
|
||||
// sysctl -w vm.nr_hugepages=new_value
|
||||
// > For more information regarding large pages please refer to:
|
||||
// https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
|
||||
// Note 1: different Linux may use different name for this property,
|
||||
// e.g. on Redhat AS-3 it is "hugetlb_pool".
|
||||
// Note 2: it's possible there's enough physical memory available but
|
||||
// they are so fragmented after a long run that they can't
|
||||
// coalesce into large pages. Try to reserve large pages when
|
||||
// the system is still "fresh".
|
||||
shm_warning_with_errno("Failed to reserve shared memory.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Attach to the region.
|
||||
char* addr = shmat_large_pages(shmid, bytes, alignment, req_addr);
|
||||
|
||||
// Remove shmid. If shmat() is successful, the actual shared memory segment
|
||||
// will be deleted when it's detached by shmdt() or when the process
|
||||
// terminates. If shmat() is not successful this will remove the shared
|
||||
// segment immediately.
|
||||
shmctl(shmid, IPC_RMID, nullptr);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static void log_on_commit_special_failure(char* req_addr, size_t bytes,
|
||||
size_t page_size, int error) {
|
||||
assert(error == ENOMEM, "Only expect to fail if no memory is available");
|
||||
@@ -4054,11 +3853,11 @@ static void log_on_commit_special_failure(char* req_addr, size_t bytes,
|
||||
byte_size_in_exact_unit(page_size), exact_unit_for_byte_size(page_size), error);
|
||||
}
|
||||
|
||||
bool os::Linux::commit_memory_special(size_t bytes,
|
||||
static bool commit_memory_special(size_t bytes,
|
||||
size_t page_size,
|
||||
char* req_addr,
|
||||
bool exec) {
|
||||
assert(UseLargePages && UseHugeTLBFS, "Should only get here when HugeTLBFS large pages are used");
|
||||
assert(UseLargePages && !UseTransparentHugePages, "Should only get here for static hugepage mode (+UseLargePages)");
|
||||
assert(is_aligned(bytes, page_size), "Unaligned size");
|
||||
assert(is_aligned(req_addr, page_size), "Unaligned address");
|
||||
assert(req_addr != nullptr, "Must have a requested address for special mappings");
|
||||
@@ -4087,16 +3886,17 @@ bool os::Linux::commit_memory_special(size_t bytes,
|
||||
return true;
|
||||
}
|
||||
|
||||
char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes,
|
||||
size_t alignment,
|
||||
size_t page_size,
|
||||
char* req_addr,
|
||||
bool exec) {
|
||||
assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
|
||||
static char* reserve_memory_special_huge_tlbfs(size_t bytes,
|
||||
size_t alignment,
|
||||
size_t page_size,
|
||||
char* req_addr,
|
||||
bool exec) {
|
||||
const os::PageSizes page_sizes = HugePages::static_info().pagesizes();
|
||||
assert(UseLargePages, "only for Huge TLBFS large pages");
|
||||
assert(is_aligned(req_addr, alignment), "Must be");
|
||||
assert(is_aligned(req_addr, page_size), "Must be");
|
||||
assert(is_aligned(alignment, os::vm_allocation_granularity()), "Must be");
|
||||
assert(_page_sizes.contains(page_size), "Must be a valid page size");
|
||||
assert(page_sizes.contains(page_size), "Must be a valid page size");
|
||||
assert(page_size > os::vm_page_size(), "Must be a large page size");
|
||||
assert(bytes >= page_size, "Shouldn't allocate large pages for small sizes");
|
||||
|
||||
@@ -4149,14 +3949,7 @@ char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_
|
||||
char* req_addr, bool exec) {
|
||||
assert(UseLargePages, "only for large pages");
|
||||
|
||||
char* addr;
|
||||
if (UseSHM) {
|
||||
// No support for using specific page sizes with SHM.
|
||||
addr = os::Linux::reserve_memory_special_shm(bytes, alignment, req_addr, exec);
|
||||
} else {
|
||||
assert(UseHugeTLBFS, "must be");
|
||||
addr = os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, page_size, req_addr, exec);
|
||||
}
|
||||
char* const addr = reserve_memory_special_huge_tlbfs(bytes, alignment, page_size, req_addr, exec);
|
||||
|
||||
if (addr != nullptr) {
|
||||
if (UseNUMAInterleaving) {
|
||||
@@ -4167,45 +3960,29 @@ char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_
|
||||
return addr;
|
||||
}
|
||||
|
||||
bool os::Linux::release_memory_special_shm(char* base, size_t bytes) {
|
||||
// detaching the SHM segment will also delete it, see reserve_memory_special_shm()
|
||||
return shmdt(base) == 0;
|
||||
}
|
||||
|
||||
bool os::Linux::release_memory_special_huge_tlbfs(char* base, size_t bytes) {
|
||||
return pd_release_memory(base, bytes);
|
||||
}
|
||||
|
||||
bool os::pd_release_memory_special(char* base, size_t bytes) {
|
||||
assert(UseLargePages, "only for large pages");
|
||||
bool res;
|
||||
|
||||
if (UseSHM) {
|
||||
res = os::Linux::release_memory_special_shm(base, bytes);
|
||||
} else {
|
||||
assert(UseHugeTLBFS, "must be");
|
||||
res = os::Linux::release_memory_special_huge_tlbfs(base, bytes);
|
||||
}
|
||||
return res;
|
||||
// Plain munmap is sufficient
|
||||
return pd_release_memory(base, bytes);
|
||||
}
|
||||
|
||||
size_t os::large_page_size() {
|
||||
return _large_page_size;
|
||||
}
|
||||
|
||||
// With SysV SHM the entire memory region must be allocated as shared
|
||||
// memory.
|
||||
// HugeTLBFS allows application to commit large page memory on demand.
|
||||
// However, when committing memory with HugeTLBFS fails, the region
|
||||
// static hugepages (hugetlbfs) allow application to commit large page memory
|
||||
// on demand.
|
||||
// However, when committing memory with hugepages fails, the region
|
||||
// that was supposed to be committed will lose the old reservation
|
||||
// and allow other threads to steal that memory region. Because of this
|
||||
// behavior we can't commit HugeTLBFS memory.
|
||||
// behavior we can't commit hugetlbfs memory. Instead, we commit that
|
||||
// memory at reservation.
|
||||
bool os::can_commit_large_page_memory() {
|
||||
return UseTransparentHugePages;
|
||||
}
|
||||
|
||||
bool os::can_execute_large_page_memory() {
|
||||
return UseTransparentHugePages || UseHugeTLBFS;
|
||||
return UseTransparentHugePages;
|
||||
}
|
||||
|
||||
char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {
|
||||
@@ -4561,12 +4338,11 @@ void os::Linux::numa_init() {
|
||||
}
|
||||
|
||||
if (UseParallelGC && UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
|
||||
// With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
|
||||
// With static large pages we cannot uncommit a page, so there's no way
|
||||
// we can make the adaptive lgrp chunk resizing work. If the user specified both
|
||||
// UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn
|
||||
// and disable adaptive resizing.
|
||||
// UseNUMA and UseLargePages on the command line - warn and disable adaptive resizing.
|
||||
if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
|
||||
warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, "
|
||||
warning("UseNUMA is not fully compatible with +UseLargePages, "
|
||||
"disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
|
||||
UseAdaptiveSizePolicy = false;
|
||||
UseAdaptiveNUMAChunkSizing = false;
|
||||
@@ -5524,7 +5300,6 @@ void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {
|
||||
if (num_found == 0) {
|
||||
st->print_cr("nothing.");
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ class os::Linux {
|
||||
friend class CgroupSubsystem;
|
||||
friend class os;
|
||||
friend class OSContainer;
|
||||
friend class TestReserveMemorySpecial;
|
||||
|
||||
static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
|
||||
static int (*_pthread_setname_np)(pthread_t, const char*);
|
||||
@@ -75,20 +74,6 @@ class os::Linux {
|
||||
static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }
|
||||
static GrowableArray<int>* nindex_to_node() { return _nindex_to_node; }
|
||||
|
||||
static bool setup_large_page_type(size_t page_size);
|
||||
static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
|
||||
static bool shm_hugetlbfs_sanity_check(bool warn, size_t page_size);
|
||||
|
||||
static int hugetlbfs_page_size_flag(size_t page_size);
|
||||
|
||||
static char* reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec);
|
||||
static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec);
|
||||
static bool commit_memory_special(size_t bytes, size_t page_size, char* req_addr, bool exec);
|
||||
|
||||
static bool release_memory_special_impl(char* base, size_t bytes);
|
||||
static bool release_memory_special_shm(char* base, size_t bytes);
|
||||
static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);
|
||||
|
||||
static void print_process_memory_info(outputStream* st);
|
||||
static void print_system_memory_info(outputStream* st);
|
||||
static bool print_container_info(outputStream* st);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user