mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-17 23:09:43 +01:00
Compare commits
474 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d36eb78ad | ||
|
|
9d1a6d1484 | ||
|
|
3059c3b69e | ||
|
|
929af9ed03 | ||
|
|
e7fdac9d5c | ||
|
|
3d32c460eb | ||
|
|
2d5cb97288 | ||
|
|
6212264cc6 | ||
|
|
32eb5290c2 | ||
|
|
c702dcabf8 | ||
|
|
c432dc008b | ||
|
|
fb822e49f2 | ||
|
|
00bb6bf509 | ||
|
|
bccd823c8e | ||
|
|
8c003d83c4 | ||
|
|
67f29b16ef | ||
|
|
1c1cb048cd | ||
|
|
b65e5eb14e | ||
|
|
6d2f6408e4 | ||
|
|
c17059dee7 | ||
|
|
96607df7f0 | ||
|
|
edfee7f348 | ||
|
|
8b9bf75880 | ||
|
|
3d8236367d | ||
|
|
2a01c798d3 | ||
|
|
fbaaac63d4 | ||
|
|
791b427f44 | ||
|
|
bcaad515fd | ||
|
|
5acd37fa96 | ||
|
|
f5e6d111b1 | ||
|
|
bcb340da09 | ||
|
|
3696765b7d | ||
|
|
5a74c2a67e | ||
|
|
52523d33dd | ||
|
|
df370d725e | ||
|
|
0d8543d677 | ||
|
|
c9cacfb25d | ||
|
|
bde650f21e | ||
|
|
be943a9fd6 | ||
|
|
d3b2ac1507 | ||
|
|
72f199024d | ||
|
|
c84af49386 | ||
|
|
fd372629f7 | ||
|
|
76afa02dab | ||
|
|
2003610b3b | ||
|
|
a474b37212 | ||
|
|
68b5aab020 | ||
|
|
f54a336cb7 | ||
|
|
f4d08ccf80 | ||
|
|
9049402a1b | ||
|
|
f1b73350c2 | ||
|
|
8700de66e4 | ||
|
|
6c0bebccb0 | ||
|
|
437342b93e | ||
|
|
39005e27d6 | ||
|
|
2865afe759 | ||
|
|
6997bfc68d | ||
|
|
16be38887f | ||
|
|
0081d8c07f | ||
|
|
5f7141982c | ||
|
|
05330227be | ||
|
|
05dad67cc2 | ||
|
|
9efdd242fb | ||
|
|
81df265e41 | ||
|
|
a6c0b10704 | ||
|
|
5c874c19cb | ||
|
|
b6233c3de7 | ||
|
|
bfd2afe5ad | ||
|
|
4c1a0fc58f | ||
|
|
a2b117ae02 | ||
|
|
8e534598b5 | ||
|
|
aeb304b29e | ||
|
|
a22ae909bc | ||
|
|
806ffb1085 | ||
|
|
52f787f675 | ||
|
|
cbfddf4e1d | ||
|
|
57fad67781 | ||
|
|
ff8cc268fd | ||
|
|
dadd9cd1e8 | ||
|
|
de237fb058 | ||
|
|
51dbd36c74 | ||
|
|
ffa33d7b80 | ||
|
|
4e5323538c | ||
|
|
19287eeeb2 | ||
|
|
8b29e127c2 | ||
|
|
7be9f1d054 | ||
|
|
b8dafa642e | ||
|
|
f2a4ed680b | ||
|
|
22642ff0aa | ||
|
|
b89172149d | ||
|
|
bf666bc0c7 | ||
|
|
de97c0eb4b | ||
|
|
f70667ea68 | ||
|
|
2063bb8ffa | ||
|
|
d8b63370f3 | ||
|
|
43d2d68da5 | ||
|
|
b058063c40 | ||
|
|
19c9388c20 | ||
|
|
b533272ecb | ||
|
|
1007618f6f | ||
|
|
790871e908 | ||
|
|
0216f5de55 | ||
|
|
21f647310b | ||
|
|
e2d6023cb9 | ||
|
|
2fd775f69c | ||
|
|
ee4d9aa4c1 | ||
|
|
5045839cb2 | ||
|
|
44a9392eca | ||
|
|
59062402b9 | ||
|
|
e01f6da1b8 | ||
|
|
8abaf11965 | ||
|
|
67204994dc | ||
|
|
bf7bd9a16c | ||
|
|
c1a568c9c4 | ||
|
|
1cc6fbd9b0 | ||
|
|
ed238e8b88 | ||
|
|
fac49b8375 | ||
|
|
fff750c99d | ||
|
|
a2544568f9 | ||
|
|
36f4b34f19 | ||
|
|
b363472265 | ||
|
|
edc0ebb780 | ||
|
|
a03eb6d3f6 | ||
|
|
f5b757ced6 | ||
|
|
1f4474f677 | ||
|
|
dd0694b9cb | ||
|
|
bf813be0f3 | ||
|
|
c84c0ab52d | ||
|
|
f368a0c12e | ||
|
|
a45b5b4921 | ||
|
|
7e0a4ed629 | ||
|
|
34f85ee94e | ||
|
|
62fd26f094 | ||
|
|
8c238eddce | ||
|
|
cd0fe37741 | ||
|
|
45c65e6b1a | ||
|
|
8643cc2133 | ||
|
|
e66a76f524 | ||
|
|
ba3c3bbd87 | ||
|
|
922f8e44ee | ||
|
|
1515bd7c9d | ||
|
|
bdee968e3e | ||
|
|
71d9a83dec | ||
|
|
d83ea92085 | ||
|
|
5cf7947ccd | ||
|
|
dc7d3b182d | ||
|
|
84cf4cb350 | ||
|
|
9e9c05f0ee | ||
|
|
c54bca6f7f | ||
|
|
95a91682c3 | ||
|
|
999e556be4 | ||
|
|
8b6293f6bf | ||
|
|
e33031b850 | ||
|
|
c5e7245096 | ||
|
|
65a0672791 | ||
|
|
e22ab10991 | ||
|
|
be900f1253 | ||
|
|
68c4286026 | ||
|
|
7dc9dd6fdf | ||
|
|
ed18222365 | ||
|
|
3e19bf88d5 | ||
|
|
ba23025cd8 | ||
|
|
7c3a39f400 | ||
|
|
e72723dc5c | ||
|
|
66520be7a7 | ||
|
|
82a63a03c0 | ||
|
|
8d9814a521 | ||
|
|
0ff2deab5d | ||
|
|
8e12053e03 | ||
|
|
e4389d8dc2 | ||
|
|
49e6121347 | ||
|
|
4ea7b36447 | ||
|
|
93bedd7aba | ||
|
|
b78896b9aa | ||
|
|
e10d14004f | ||
|
|
c2e77e2f17 | ||
|
|
9fd855ed47 | ||
|
|
b8ae4a8c09 | ||
|
|
e5aed6be7a | ||
|
|
b922f8d459 | ||
|
|
35e9662767 | ||
|
|
cb1d25fcfa | ||
|
|
2b7fc0506a | ||
|
|
af942a693b | ||
|
|
26de9e247a | ||
|
|
b530c0281b | ||
|
|
e70cb4e6c7 | ||
|
|
d89602a53f | ||
|
|
3bd9042054 | ||
|
|
525063be90 | ||
|
|
c1282b57f5 | ||
|
|
5ba69e1734 | ||
|
|
c96cbe481c | ||
|
|
a7db4feceb | ||
|
|
b86c3b7a68 | ||
|
|
475306b757 | ||
|
|
f016934184 | ||
|
|
2174f6646e | ||
|
|
16170678a7 | ||
|
|
2806adee2d | ||
|
|
ec38505720 | ||
|
|
d2d58dd6a8 | ||
|
|
b2a39c5767 | ||
|
|
679f526d89 | ||
|
|
2e472fe7ea | ||
|
|
88dafe564f | ||
|
|
8d9479910f | ||
|
|
9847086466 | ||
|
|
40861761c2 | ||
|
|
88378ed058 | ||
|
|
8569227473 | ||
|
|
f4ca41ad75 | ||
|
|
376051a9be | ||
|
|
a5071e010b | ||
|
|
28d8149c69 | ||
|
|
e9f7db3045 | ||
|
|
aba19334ea | ||
|
|
f3be138eb8 | ||
|
|
bc05893f82 | ||
|
|
dd8ae61643 | ||
|
|
ee98d26218 | ||
|
|
886386c039 | ||
|
|
438ab7c115 | ||
|
|
52c7ff1d81 | ||
|
|
ff499ef79f | ||
|
|
37a61720b6 | ||
|
|
7d42aa1513 | ||
|
|
6e9671a8a8 | ||
|
|
52a6c37558 | ||
|
|
075fed91bd | ||
|
|
30f93a29c2 | ||
|
|
4cf131a101 | ||
|
|
7286f5291d | ||
|
|
07fce8eff2 | ||
|
|
176606d0cb | ||
|
|
8ae309ebac | ||
|
|
841ab487f8 | ||
|
|
61ebe3b0c4 | ||
|
|
ca9635df33 | ||
|
|
8a4dc79e1a | ||
|
|
d78e8dab93 | ||
|
|
24823ba647 | ||
|
|
d47393bd82 | ||
|
|
387828a3f7 | ||
|
|
c4a83bd6f6 | ||
|
|
827c71dac9 | ||
|
|
2acb5bd992 | ||
|
|
c8fa3e21e6 | ||
|
|
57a65fe436 | ||
|
|
c90768c93b | ||
|
|
29397d29ba | ||
|
|
fc04750817 | ||
|
|
458e563cd9 | ||
|
|
71aac7a5fb | ||
|
|
09c6c4ff02 | ||
|
|
eb9e754b3a | ||
|
|
a40d397d5d | ||
|
|
7edd10e5fa | ||
|
|
d75d876edd | ||
|
|
e44276989f | ||
|
|
3560e680bc | ||
|
|
faa9c6909d | ||
|
|
ace010b38a | ||
|
|
be4614eb5e | ||
|
|
35a1b77da5 | ||
|
|
46965a096c | ||
|
|
700c25f5b4 | ||
|
|
631a9f60f3 | ||
|
|
ed9f3243f0 | ||
|
|
ade21a965f | ||
|
|
f0cfd361bd | ||
|
|
78623c95f2 | ||
|
|
f0e2e4311b | ||
|
|
3dc4bd8581 | ||
|
|
1d1cd32bc3 | ||
|
|
868f8745fa | ||
|
|
2a9c3589d9 | ||
|
|
5235cc987d | ||
|
|
3b1e56a427 | ||
|
|
3fbccb01dc | ||
|
|
ad31ec5c5f | ||
|
|
15cf8f8531 | ||
|
|
ade40741ca | ||
|
|
ea19e9c6aa | ||
|
|
d33dfe5cb2 | ||
|
|
27d5f5c237 | ||
|
|
df22fb322e | ||
|
|
c3cd1f1814 | ||
|
|
dd517c6404 | ||
|
|
83564ea5f3 | ||
|
|
bbe0079d98 | ||
|
|
730663649f | ||
|
|
1369c545ac | ||
|
|
4db7a1c3bb | ||
|
|
755722ced6 | ||
|
|
1cf9335b24 | ||
|
|
13c11487f7 | ||
|
|
028ec7e744 | ||
|
|
54b3ceeca2 | ||
|
|
30a0c61de0 | ||
|
|
409a39ec8d | ||
|
|
296c5b645a | ||
|
|
cc9ab5f197 | ||
|
|
1551928502 | ||
|
|
b67b71cd87 | ||
|
|
7eb25ec7b3 | ||
|
|
539da24863 | ||
|
|
a8e4229852 | ||
|
|
cbe329b90a | ||
|
|
06dd735342 | ||
|
|
9ab29f8dcd | ||
|
|
ba426d6887 | ||
|
|
18cdc903cf | ||
|
|
fcf8368eb1 | ||
|
|
a678416994 | ||
|
|
122bc7770e | ||
|
|
e9e694f4ef | ||
|
|
da1091eed9 | ||
|
|
c2477a5cad | ||
|
|
2cf5f01397 | ||
|
|
38042ad4e9 | ||
|
|
51238c4bdb | ||
|
|
9481d06e62 | ||
|
|
a5cf4210cd | ||
|
|
f9aec02f3c | ||
|
|
7455b1b527 | ||
|
|
d4fb30885b | ||
|
|
d786c49525 | ||
|
|
5852f3eafe | ||
|
|
be0e1c7b14 | ||
|
|
7c1d481d6d | ||
|
|
518ec97114 | ||
|
|
32d80e2caf | ||
|
|
19147f326c | ||
|
|
2a59243cba | ||
|
|
4fc6b0ffa4 | ||
|
|
28c82bf18d | ||
|
|
7263e25d9b | ||
|
|
f695ca5884 | ||
|
|
93fedc12db | ||
|
|
1230853343 | ||
|
|
dce7a5732e | ||
|
|
c53f845ec9 | ||
|
|
84c2379285 | ||
|
|
3b908c4781 | ||
|
|
1802601a12 | ||
|
|
6de23bf36e | ||
|
|
aff659aaf7 | ||
|
|
05745e3f1d | ||
|
|
e8768ae08d | ||
|
|
f6fe39ff11 | ||
|
|
e204242118 | ||
|
|
2d609557ff | ||
|
|
e0bad5153b | ||
|
|
424c58f3e9 | ||
|
|
14dab319a8 | ||
|
|
5fcac7c846 | ||
|
|
2f917bff5c | ||
|
|
7db69e6a12 | ||
|
|
f7dc257a20 | ||
|
|
97db670956 | ||
|
|
51be857f3c | ||
|
|
0f8e4e0a81 | ||
|
|
6313223bcd | ||
|
|
3bc5679cab | ||
|
|
be49dabd0d | ||
|
|
ac968c36d7 | ||
|
|
0ad6c9e3d9 | ||
|
|
fff2e580cd | ||
|
|
7b4d62c794 | ||
|
|
76637c53c5 | ||
|
|
59073fa3eb | ||
|
|
808a03927c | ||
|
|
459957f30a | ||
|
|
b98d13fc3c | ||
|
|
4f3de09672 | ||
|
|
1fde8b868a | ||
|
|
66aeb89469 | ||
|
|
a5122d7f6c | ||
|
|
c0a3b76958 | ||
|
|
7e1d26dd5c | ||
|
|
5584ba36c6 | ||
|
|
75d382d3db | ||
|
|
febf8af4b5 | ||
|
|
10335f60f9 | ||
|
|
ecff9c1ef7 | ||
|
|
a247d0c74b | ||
|
|
341b4e09b7 | ||
|
|
f696796e88 | ||
|
|
413dbf8757 | ||
|
|
f553819502 | ||
|
|
34351b7a79 | ||
|
|
b061b6678f | ||
|
|
dcdcd48d8f | ||
|
|
87ef73329f | ||
|
|
05f7f0ade2 | ||
|
|
6311dabe68 | ||
|
|
bdebf198bb | ||
|
|
20de541b13 | ||
|
|
b31454e362 | ||
|
|
0be0775a76 | ||
|
|
6dfb8120c2 | ||
|
|
a7dde578a8 | ||
|
|
692be57738 | ||
|
|
d02bc873f8 | ||
|
|
8b24851b9d | ||
|
|
c328f9589d | ||
|
|
fde5b16817 | ||
|
|
45a9ade337 | ||
|
|
62b7c5eaed | ||
|
|
69014cd55b | ||
|
|
5a97dbf606 | ||
|
|
2838a916ab | ||
|
|
d2ba3b1ef7 | ||
|
|
d632d743e0 | ||
|
|
ddbbd36e4b | ||
|
|
c8ad7b7f84 | ||
|
|
cf948548c3 | ||
|
|
7ece9e90c0 | ||
|
|
9320ef9b29 | ||
|
|
2a565ff368 | ||
|
|
493b5bd2fd | ||
|
|
f573f6d233 | ||
|
|
8a0a6f8c25 | ||
|
|
3d9d353edb | ||
|
|
1b621f5527 | ||
|
|
5463c9cd9a | ||
|
|
ac07355f55 | ||
|
|
4fb5c12813 | ||
|
|
d5a96e3f49 | ||
|
|
aadf36809c | ||
|
|
a3447ec656 | ||
|
|
b25ed57b76 | ||
|
|
df4ed7eff7 | ||
|
|
5718039a46 | ||
|
|
c51685267c | ||
|
|
7d903964fb | ||
|
|
6f4824068d | ||
|
|
e1fd663f22 | ||
|
|
d5214a4288 | ||
|
|
2611a49ea1 | ||
|
|
b8c0b2fd8c | ||
|
|
973bcdab81 | ||
|
|
6359b4ec23 | ||
|
|
ce4b257fa5 | ||
|
|
b270f30d10 | ||
|
|
486594d427 | ||
|
|
ce8399fd60 | ||
|
|
3c6459e1de | ||
|
|
92fd490f22 | ||
|
|
d13302f8b0 | ||
|
|
ce108446ca | ||
|
|
5c12a182e3 | ||
|
|
71800884f6 | ||
|
|
0c178beb69 | ||
|
|
6c13a3032f | ||
|
|
5e6bfc5eaa | ||
|
|
2c2d4d2cde | ||
|
|
0eb299af79 | ||
|
|
b893a2b2f7 | ||
|
|
05f950934e | ||
|
|
701bc3bbbe | ||
|
|
9e48b90c7f | ||
|
|
bad5edf146 | ||
|
|
f577385fc8 | ||
|
|
86623aa41d | ||
|
|
af5c49226c | ||
|
|
cb7e3d263a | ||
|
|
25dc4762b4 | ||
|
|
11e4a925be | ||
|
|
354ea4c28f | ||
|
|
959a443a9e | ||
|
|
4ed38f5ad5 | ||
|
|
fe4c0a2f04 |
18
.github/scripts/gen-test-results.sh
vendored
18
.github/scripts/gen-test-results.sh
vendored
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -44,8 +44,8 @@ for test in $failures $errors; do
|
||||
base_path="$(echo "$test" | tr '#' '_')"
|
||||
report_file="$report_dir/$base_path.jtr"
|
||||
hs_err_files=$(ls $report_dir/$base_path/hs_err*.log 2> /dev/null || true)
|
||||
replay_files=$(ls $report_dir/$base_path/replay*.log 2> /dev/null || true)
|
||||
echo "#### <a id="$anchor">$test"
|
||||
|
||||
echo '<details><summary>View test results</summary>'
|
||||
echo ''
|
||||
echo '```'
|
||||
@@ -73,6 +73,20 @@ for test in $failures $errors; do
|
||||
echo ''
|
||||
fi
|
||||
|
||||
if [[ "$replay_files" != "" ]]; then
|
||||
echo '<details><summary>View HotSpot replay file</summary>'
|
||||
echo ''
|
||||
for replay in $replay_files; do
|
||||
echo '```'
|
||||
echo "$replay:"
|
||||
echo ''
|
||||
cat "$replay"
|
||||
echo '```'
|
||||
done
|
||||
|
||||
echo '</details>'
|
||||
echo ''
|
||||
fi
|
||||
done >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# With many failures, the summary can easily exceed 1024 kB, the limit set by Github
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright 2015 Google, Inc. All Rights Reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
@@ -26,12 +27,17 @@ usage() {
|
||||
echo "$0 DIR ..."
|
||||
echo "Modifies in place all the java source files found"
|
||||
echo "in the given directories so that all java language modifiers"
|
||||
echo "are in the canonical order given by Modifier#toString()."
|
||||
echo "are in the canonical order."
|
||||
echo "Tries to get it right even within javadoc comments,"
|
||||
echo "and even if the list of modifiers spans 2 lines."
|
||||
echo
|
||||
echo "See:"
|
||||
echo "https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Modifier.html#toString-int-"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.1.1"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.3.1"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.4.3"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.8.3"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.1.1"
|
||||
echo "https://docs.oracle.com/javase/specs/jls/se21/html/jls-9.html#jls-9.4"
|
||||
echo
|
||||
echo "Example:"
|
||||
echo "$0 jdk/src/java.base jdk/test/java/{util,io,lang}"
|
||||
@@ -46,7 +52,7 @@ for dir in "${dirs[@]}"; do [[ -d "$dir" ]] || usage; done
|
||||
|
||||
declare -ar modifiers=(
|
||||
public protected private
|
||||
abstract static final transient
|
||||
abstract default static final sealed non-sealed transient
|
||||
volatile synchronized native strictfp
|
||||
)
|
||||
declare -r SAVE_IFS="$IFS"
|
||||
|
||||
@@ -753,6 +753,8 @@ macOS.</p>
|
||||
<code>sudo apt-get install libfontconfig-dev</code>.</li>
|
||||
<li>To install on an rpm-based Linux, try running
|
||||
<code>sudo yum install fontconfig-devel</code>.</li>
|
||||
<li>To install on Alpine Linux, try running
|
||||
<code>sudo apk add fontconfig-dev</code>.</li>
|
||||
</ul>
|
||||
<p>Use <code>--with-fontconfig-include=<path></code> and
|
||||
<code>--with-fontconfig=<path></code> if <code>configure</code>
|
||||
@@ -1499,9 +1501,7 @@ like this:</p>
|
||||
--resolve-deps \
|
||||
buster \
|
||||
~/sysroot-arm64 \
|
||||
https://httpredir.debian.org/debian/</code></pre>
|
||||
<p>If the target architecture is <code>riscv64</code>, the path should
|
||||
be <code>debian-ports</code> instead of <code>debian</code>.</p></li>
|
||||
https://httpredir.debian.org/debian/</code></pre></li>
|
||||
<li><p>To create an Ubuntu-based chroot:</p>
|
||||
<pre><code>sudo debootstrap \
|
||||
--arch=arm64 \
|
||||
|
||||
@@ -572,6 +572,7 @@ required on all platforms except Windows and macOS.
|
||||
libfontconfig-dev`.
|
||||
* To install on an rpm-based Linux, try running `sudo yum install
|
||||
fontconfig-devel`.
|
||||
* To install on Alpine Linux, try running `sudo apk add fontconfig-dev`.
|
||||
|
||||
Use `--with-fontconfig-include=<path>` and `--with-fontconfig=<path>` if
|
||||
`configure` does not automatically locate the platform Fontconfig files.
|
||||
@@ -1316,9 +1317,6 @@ For example, cross-compiling to AArch64 from x86_64 could be done like this:
|
||||
https://httpredir.debian.org/debian/
|
||||
```
|
||||
|
||||
If the target architecture is `riscv64`, the path should be `debian-ports`
|
||||
instead of `debian`.
|
||||
|
||||
* To create an Ubuntu-based chroot:
|
||||
|
||||
```
|
||||
|
||||
@@ -58,7 +58,7 @@ DEMO_MANIFEST := $(SUPPORT_OUTPUTDIR)/demos/java-main-manifest.mf
|
||||
# This rule will be depended on due to the MANIFEST line in SetupBuildDemo
|
||||
# and SetupBuildJvmtiDemo.
|
||||
$(eval $(call SetupTextFileProcessing, BUILD_JAVA_MANIFEST, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf.template, \
|
||||
OUTPUT_FILE := $(DEMO_MANIFEST), \
|
||||
REPLACEMENTS := \
|
||||
@@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION) ; \
|
||||
|
||||
@@ -139,11 +139,6 @@ ifeq ($(IS_DRAFT), true)
|
||||
endif
|
||||
DRAFT_TEXT := This specification is not final and is subject to change. \
|
||||
Use is subject to <a href="$(LICENSE_URL)">license terms</a>.
|
||||
|
||||
# Workaround stylesheet bug
|
||||
HEADER_STYLE := style="margin-top: 9px;"
|
||||
else
|
||||
HEADER_STYLE := style="margin-top: 14px;"
|
||||
endif
|
||||
|
||||
# $1 - Relative prefix to COPYRIGHT_URL
|
||||
@@ -339,7 +334,7 @@ define SetupApiDocsGenerationBody
|
||||
$1_DOC_TITLE := $$($1_LONG_NAME)<br>Version $$(VERSION_SPECIFICATION) API \
|
||||
Specification
|
||||
$1_WINDOW_TITLE := $$(subst &,&,$$($1_SHORT_NAME))$$(DRAFT_MARKER_TITLE)
|
||||
$1_HEADER_TITLE := <div $$(HEADER_STYLE)><strong>$$($1_SHORT_NAME)</strong> \
|
||||
$1_HEADER_TITLE := <div><strong>$$($1_SHORT_NAME)</strong> \
|
||||
$$(DRAFT_MARKER_STR)</div>
|
||||
ifneq ($$($1_OTHER_VERSIONS), )
|
||||
$1_JAVADOC_BOTTOM := $$(call JAVADOC_BOTTOM, <a href="$$($1_OTHER_VERSIONS)">Other versions.</a>)
|
||||
@@ -647,7 +642,7 @@ ifeq ($(ENABLE_PANDOC), true)
|
||||
GLOBAL_SPECS_DEFAULT_CSS_FILE := $(DOCS_OUTPUTDIR)/resources/jdk-default.css
|
||||
# Unset the following to suppress the link to the tool guides
|
||||
NAV_LINK_GUIDES := --nav-link-guides
|
||||
HEADER_RIGHT_SIDE_INFO := <strong>$(subst &,&,$(JDK_SHORT_NAME))$(DRAFT_MARKER_STR)</strong>
|
||||
HEADER_RIGHT_SIDE_INFO := <strong>$(subst &,&,$(JDK_SHORT_NAME))</strong>$(DRAFT_MARKER_STR)
|
||||
|
||||
$(foreach m, $(ALL_MODULES), \
|
||||
$(eval SPECS_$m := $(call FindModuleSpecsDirs, $m)) \
|
||||
|
||||
@@ -33,7 +33,7 @@ include TextFileProcessing.gmk
|
||||
|
||||
# This rule will be depended on due to the MANIFEST line
|
||||
$(eval $(call SetupTextFileProcessing, BUILD_JAVA_MANIFEST, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf.template, \
|
||||
OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/java-main-manifest.mf, \
|
||||
REPLACEMENTS := \
|
||||
@@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION) ; \
|
||||
|
||||
@@ -69,7 +69,7 @@ ifeq ($(call isTargetOs, macosx), true)
|
||||
))
|
||||
|
||||
$(eval $(call SetupTextFileProcessing, BUILD_JDK_PLIST, \
|
||||
SOURCE_FILES := $(MACOSX_PLIST_SRC)/JDK-Info.plist, \
|
||||
SOURCE_FILES := $(MACOSX_PLIST_SRC)/JDK-Info.plist.template, \
|
||||
OUTPUT_FILE := $(JDK_MACOSX_CONTENTS_DIR)/Info.plist, \
|
||||
REPLACEMENTS := \
|
||||
@@ID@@ => $(MACOSX_BUNDLE_ID_BASE).jdk ; \
|
||||
@@ -82,7 +82,7 @@ ifeq ($(call isTargetOs, macosx), true)
|
||||
))
|
||||
|
||||
$(eval $(call SetupTextFileProcessing, BUILD_JRE_PLIST, \
|
||||
SOURCE_FILES := $(MACOSX_PLIST_SRC)/JRE-Info.plist, \
|
||||
SOURCE_FILES := $(MACOSX_PLIST_SRC)/JRE-Info.plist.template, \
|
||||
OUTPUT_FILE := $(JRE_MACOSX_CONTENTS_DIR)/Info.plist, \
|
||||
REPLACEMENTS := \
|
||||
@@ID@@ => $(MACOSX_BUNDLE_ID_BASE).jre ; \
|
||||
|
||||
@@ -744,9 +744,16 @@ endif
|
||||
|
||||
$(eval $(call SetupTarget, build-test-lib, \
|
||||
MAKEFILE := test/BuildTestLib, \
|
||||
TARGET := build-test-lib, \
|
||||
DEPS := exploded-image, \
|
||||
))
|
||||
|
||||
$(eval $(call SetupTarget, test-image-lib, \
|
||||
MAKEFILE := test/BuildTestLib, \
|
||||
TARGET := test-image-lib, \
|
||||
DEPS := build-test-lib, \
|
||||
))
|
||||
|
||||
ifeq ($(BUILD_FAILURE_HANDLER), true)
|
||||
# Builds the failure handler jtreg extension
|
||||
$(eval $(call SetupTarget, build-test-failure-handler, \
|
||||
@@ -781,7 +788,7 @@ endif
|
||||
|
||||
$(eval $(call SetupTarget, build-microbenchmark, \
|
||||
MAKEFILE := test/BuildMicrobenchmark, \
|
||||
DEPS := interim-langtools exploded-image, \
|
||||
DEPS := interim-langtools exploded-image build-test-lib, \
|
||||
))
|
||||
|
||||
################################################################################
|
||||
@@ -962,20 +969,28 @@ else
|
||||
|
||||
jdk.jdeps-gendata: java
|
||||
|
||||
# The ct.sym generation uses all the moduleinfos as input
|
||||
jdk.compiler-gendata: $(GENSRC_MODULEINFO_TARGETS) $(JAVA_TARGETS)
|
||||
# jdk.compiler-gendata needs the BUILD_JDK. If the BUILD_JDK was supplied
|
||||
# externally, no extra prerequisites are needed.
|
||||
# jdk.compiler gendata generates ct.sym, which requires all generated
|
||||
# java source and compiled classes present.
|
||||
jdk.compiler-gendata: $(JAVA_TARGETS)
|
||||
|
||||
# jdk.javadoc gendata generates element-list, which requires all java sources
|
||||
# but not compiled classes.
|
||||
jdk.javadoc-gendata: $(GENSRC_TARGETS)
|
||||
|
||||
# ct.sym and element-list generation also needs the BUILD_JDK. If the
|
||||
# BUILD_JDK was supplied externally, no extra prerequisites are needed.
|
||||
ifeq ($(CREATE_BUILDJDK), true)
|
||||
ifneq ($(CREATING_BUILDJDK), true)
|
||||
# When cross compiling and an external BUILD_JDK wasn't supplied, it's
|
||||
# produced by the create-buildjdk target.
|
||||
jdk.compiler-gendata: create-buildjdk
|
||||
jdk.javadoc-gendata: create-buildjdk
|
||||
endif
|
||||
else ifeq ($(EXTERNAL_BUILDJDK), false)
|
||||
# When not cross compiling, the BUILD_JDK is the interim jdk image, and
|
||||
# the javac launcher is needed.
|
||||
jdk.compiler-gendata: jdk.compiler-launchers
|
||||
jdk.javadoc-gendata: jdk.compiler-launchers
|
||||
endif
|
||||
|
||||
# Declare dependencies between jmod targets.
|
||||
@@ -1264,7 +1279,7 @@ all-docs-bundles: docs-jdk-bundles docs-javase-bundles docs-reference-bundles
|
||||
# This target builds the test image
|
||||
test-image: prepare-test-image test-image-jdk-jtreg-native \
|
||||
test-image-demos-jdk test-image-libtest-jtreg-native \
|
||||
test-image-lib-native
|
||||
test-image-lib test-image-lib-native
|
||||
|
||||
ifneq ($(JVM_TEST_IMAGE_TARGETS), )
|
||||
# If JVM_TEST_IMAGE_TARGETS is externally defined, use it instead of the
|
||||
|
||||
@@ -620,11 +620,16 @@ define SetupRunMicroTestBody
|
||||
$1_MICRO_WARMUP_TIME := -w $$(MICRO_WARMUP_TIME)
|
||||
endif
|
||||
|
||||
# Microbenchmarks are executed from the root of the test image directory.
|
||||
# This enables JMH tests to add dependencies using relative paths such as
|
||||
# -Djava.library.path=micro/native
|
||||
|
||||
run-test-$1: pre-run-test
|
||||
$$(call LogWarn)
|
||||
$$(call LogWarn, Running test '$$($1_TEST)')
|
||||
$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR))
|
||||
$$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/micro, ( \
|
||||
$$(CD) $$(TEST_IMAGE_DIR) && \
|
||||
$$(FIXPATH) $$($1_MICRO_TEST_JDK)/bin/java $$($1_MICRO_JAVA_OPTIONS) \
|
||||
-jar $$($1_MICRO_BENCHMARKS_JAR) \
|
||||
$$($1_MICRO_ITER) $$($1_MICRO_FORK) $$($1_MICRO_TIME) \
|
||||
|
||||
@@ -448,17 +448,17 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
|
||||
AC_SUBST(CONFIGURESUPPORT_OUTPUTDIR)
|
||||
|
||||
# The spec.gmk file contains all variables for the make system.
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/spec.gmk:$AUTOCONF_DIR/spec.gmk.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/spec.gmk:$AUTOCONF_DIR/spec.gmk.template])
|
||||
# The bootcycle-spec.gmk file contains support for boot cycle builds.
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.template])
|
||||
# The buildjdk-spec.gmk file contains support for building a buildjdk when cross compiling.
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/buildjdk-spec.gmk:$AUTOCONF_DIR/buildjdk-spec.gmk.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/buildjdk-spec.gmk:$AUTOCONF_DIR/buildjdk-spec.gmk.template])
|
||||
# The compare.sh is used to compare the build output to other builds.
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/compare.sh:$AUTOCONF_DIR/compare.sh.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/compare.sh:$AUTOCONF_DIR/compare.sh.template])
|
||||
# The generated Makefile knows where the spec.gmk is and where the source is.
|
||||
# You can run make from the OUTPUTDIR, or from the top-level Makefile
|
||||
# which will look for generated configurations
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/Makefile:$AUTOCONF_DIR/Makefile.in])
|
||||
AC_CONFIG_FILES([$OUTPUTDIR/Makefile:$AUTOCONF_DIR/Makefile.template])
|
||||
])
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -117,6 +117,11 @@ AC_DEFUN([FLAGS_SETUP_DEBUG_SYMBOLS],
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${DEBUG_PREFIX_CFLAGS}],
|
||||
IF_FALSE: [
|
||||
DEBUG_PREFIX_CFLAGS=
|
||||
],
|
||||
IF_TRUE: [
|
||||
# Add debug prefix map gcc system include paths, as they cause
|
||||
# non-deterministic debug paths depending on gcc path location.
|
||||
DEBUG_PREFIX_MAP_GCC_INCLUDE_PATHS
|
||||
]
|
||||
)
|
||||
fi
|
||||
@@ -158,6 +163,55 @@ AC_DEFUN([FLAGS_SETUP_DEBUG_SYMBOLS],
|
||||
AC_SUBST(ASFLAGS_DEBUG_SYMBOLS)
|
||||
])
|
||||
|
||||
# gcc will embed the full system include paths in the debug info
|
||||
# resulting in non-deterministic debug symbol files and thus
|
||||
# non-reproducible native libraries if gcc includes are located
|
||||
# in different paths.
|
||||
# Add -fdebug-prefix-map'ings for root and gcc include paths,
|
||||
# pointing to a common set of folders so that the binaries are deterministic:
|
||||
# root include : /usr/include
|
||||
# gcc include : /usr/local/gcc_include
|
||||
# g++ include : /usr/local/gxx_include
|
||||
AC_DEFUN([DEBUG_PREFIX_MAP_GCC_INCLUDE_PATHS],
|
||||
[
|
||||
# Determine gcc system include paths.
|
||||
# Assume default roots to start with:
|
||||
GCC_ROOT_INCLUDE="/usr/include"
|
||||
|
||||
# Determine is sysroot or devkit specified?
|
||||
if test "x$SYSROOT" != "x"; then
|
||||
GCC_ROOT_INCLUDE="${SYSROOT%/}/usr/include"
|
||||
fi
|
||||
|
||||
# Add root include mapping => /usr/include
|
||||
GCC_INCLUDE_DEBUG_MAP_FLAGS="-fdebug-prefix-map=${GCC_ROOT_INCLUDE}/=/usr/include/"
|
||||
|
||||
# Add gcc system include mapping => /usr/local/gcc_include
|
||||
# Find location of stddef.h using build C compiler
|
||||
GCC_SYSTEM_INCLUDE=`$ECHO "#include <stddef.h>" | \
|
||||
$CC $CFLAGS -v -E - 2>&1 | \
|
||||
$GREP stddef | $TAIL -1 | $TR -s " " | $CUT -d'"' -f2`
|
||||
if test "x$GCC_SYSTEM_INCLUDE" != "x"; then
|
||||
GCC_SYSTEM_INCLUDE=`$DIRNAME $GCC_SYSTEM_INCLUDE`
|
||||
GCC_INCLUDE_DEBUG_MAP_FLAGS="$GCC_INCLUDE_DEBUG_MAP_FLAGS \
|
||||
-fdebug-prefix-map=${GCC_SYSTEM_INCLUDE}/=/usr/local/gcc_include/"
|
||||
fi
|
||||
|
||||
# Add g++ system include mapping => /usr/local/gxx_include
|
||||
# Find location of cstddef using build C++ compiler
|
||||
GXX_SYSTEM_INCLUDE=`$ECHO "#include <cstddef>" | \
|
||||
$CXX $CXXFLAGS -v -E -x c++ - 2>&1 | \
|
||||
$GREP cstddef | $TAIL -1 | $TR -s " " | $CUT -d'"' -f2`
|
||||
if test "x$GXX_SYSTEM_INCLUDE" != "x"; then
|
||||
GXX_SYSTEM_INCLUDE=`$DIRNAME $GXX_SYSTEM_INCLUDE`
|
||||
GCC_INCLUDE_DEBUG_MAP_FLAGS="$GCC_INCLUDE_DEBUG_MAP_FLAGS \
|
||||
-fdebug-prefix-map=${GXX_SYSTEM_INCLUDE}/=/usr/local/gxx_include/"
|
||||
fi
|
||||
|
||||
# Add to debug prefix cflags
|
||||
DEBUG_PREFIX_CFLAGS="$DEBUG_PREFIX_CFLAGS $GCC_INCLUDE_DEBUG_MAP_FLAGS"
|
||||
])
|
||||
|
||||
AC_DEFUN([FLAGS_SETUP_WARNINGS],
|
||||
[
|
||||
# Set default value.
|
||||
@@ -425,7 +479,7 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER],
|
||||
[
|
||||
#### OS DEFINES, these should be independent on toolchain
|
||||
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
CFLAGS_OS_DEF_JVM="-DLINUX"
|
||||
CFLAGS_OS_DEF_JVM="-DLINUX -D_FILE_OFFSET_BITS=64"
|
||||
CFLAGS_OS_DEF_JDK="-D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
|
||||
elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
||||
CFLAGS_OS_DEF_JVM="-D_ALLBSD_SOURCE -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
|
||||
|
||||
@@ -110,6 +110,15 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS],
|
||||
CHECK_VALUE: [UTIL_CHECK_STRING_NON_EMPTY_PRINTABLE])
|
||||
AC_SUBST(COMPANY_NAME)
|
||||
|
||||
# Set the JDK RC Company name
|
||||
# Otherwise uses the value set for "vendor-name".
|
||||
UTIL_ARG_WITH(NAME: jdk-rc-company-name, TYPE: string,
|
||||
DEFAULT: $COMPANY_NAME,
|
||||
DESC: [Set JDK RC company name. This is used for CompanyName properties of MS Windows binaries.],
|
||||
DEFAULT_DESC: [from branding.conf],
|
||||
CHECK_VALUE: [UTIL_CHECK_STRING_NON_EMPTY_PRINTABLE])
|
||||
AC_SUBST(JDK_RC_COMPANY_NAME)
|
||||
|
||||
# The vendor URL, if any
|
||||
# Only set VENDOR_URL if '--with-vendor-url' was used and is not empty.
|
||||
# Otherwise we will use the value from "branding.conf" included above.
|
||||
|
||||
@@ -191,6 +191,7 @@ PRODUCT_NAME := @PRODUCT_NAME@
|
||||
PRODUCT_SUFFIX := @PRODUCT_SUFFIX@
|
||||
JDK_RC_PLATFORM_NAME := @JDK_RC_PLATFORM_NAME@
|
||||
JDK_RC_NAME := @JDK_RC_NAME@
|
||||
JDK_RC_COMPANY_NAME := @JDK_RC_COMPANY_NAME@
|
||||
COMPANY_NAME := @COMPANY_NAME@
|
||||
HOTSPOT_VM_DISTRO := @HOTSPOT_VM_DISTRO@
|
||||
MACOSX_BUNDLE_NAME_BASE := @MACOSX_BUNDLE_NAME_BASE@
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -389,6 +389,10 @@ AC_DEFUN_ONCE([TOOLCHAIN_POST_DETECTION],
|
||||
# This is necessary since AC_PROG_CC defaults CFLAGS to "-g -O2"
|
||||
CFLAGS="$ORG_CFLAGS"
|
||||
CXXFLAGS="$ORG_CXXFLAGS"
|
||||
|
||||
# filter out some unwanted additions autoconf may add to CXX; we saw this on macOS with autoconf 2.72
|
||||
UTIL_GET_NON_MATCHING_VALUES(cxx_filtered, $CXX, -std=c++11 -std=gnu++11)
|
||||
CXX="$cxx_filtered"
|
||||
])
|
||||
|
||||
# Check if a compiler is of the toolchain type we expect, and save the version
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -199,7 +199,7 @@ AC_DEFUN([UTIL_GET_NON_MATCHING_VALUES],
|
||||
if test -z "$legal_values"; then
|
||||
$1="$2"
|
||||
else
|
||||
result=`$GREP -Fvx "$legal_values" <<< "$values_to_check" | $GREP -v '^$'`
|
||||
result=`$GREP -Fvx -- "$legal_values" <<< "$values_to_check" | $GREP -v '^$'`
|
||||
$1=${result//$'\n'/ }
|
||||
fi
|
||||
])
|
||||
@@ -226,7 +226,7 @@ AC_DEFUN([UTIL_GET_MATCHING_VALUES],
|
||||
if test -z "$illegal_values"; then
|
||||
$1=""
|
||||
else
|
||||
result=`$GREP -Fx "$illegal_values" <<< "$values_to_check" | $GREP -v '^$'`
|
||||
result=`$GREP -Fx -- "$illegal_values" <<< "$values_to_check" | $GREP -v '^$'`
|
||||
$1=${result//$'\n'/ }
|
||||
fi
|
||||
])
|
||||
|
||||
@@ -98,7 +98,7 @@ GLOBAL_VERSION_INFO_RESOURCE := $(TOPDIR)/src/java.base/windows/native/common/ve
|
||||
|
||||
JDK_RCFLAGS=$(RCFLAGS) \
|
||||
-D"JDK_VERSION_STRING=$(VERSION_STRING)" \
|
||||
-D"JDK_COMPANY=$(COMPANY_NAME)" \
|
||||
-D"JDK_COMPANY=$(JDK_RC_COMPANY_NAME)" \
|
||||
-D"JDK_VER=$(VERSION_NUMBER_FOUR_POSITIONS)" \
|
||||
-D"JDK_COPYRIGHT=Copyright \xA9 $(COPYRIGHT_YEAR)" \
|
||||
-D"JDK_NAME=$(JDK_RC_NAME) $(VERSION_SHORT)" \
|
||||
|
||||
@@ -112,7 +112,7 @@ define SetupBuildLauncherBody
|
||||
$1_PLIST_FILE := $$(SUPPORT_OUTPUTDIR)/native/$$(MODULE)/$1/Info.plist
|
||||
|
||||
$$(eval $$(call SetupTextFileProcessing, BUILD_PLIST_$1, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/bundle/cmdline-Info.plist, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/data/bundle/cmdline-Info.plist.template, \
|
||||
OUTPUT_FILE := $$($1_PLIST_FILE), \
|
||||
REPLACEMENTS := \
|
||||
@@ID@@ => $(MACOSX_BUNDLE_ID_BASE).$1 ; \
|
||||
|
||||
@@ -1206,7 +1206,7 @@ var getJibProfilesDependencies = function (input, common) {
|
||||
|
||||
jcov: {
|
||||
organization: common.organization,
|
||||
revision: "3.0-15-jdk-asm+1.0",
|
||||
revision: "3.0-16-jdk-asm+1.0",
|
||||
ext: "zip",
|
||||
environment_name: "JCOV_HOME",
|
||||
},
|
||||
|
||||
@@ -223,6 +223,7 @@ JVM_VirtualThreadEnd
|
||||
JVM_VirtualThreadMount
|
||||
JVM_VirtualThreadUnmount
|
||||
JVM_VirtualThreadHideFrames
|
||||
JVM_VirtualThreadDisableSuspend
|
||||
|
||||
# Scoped values
|
||||
JVM_EnsureMaterializedForStackWalk_func
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -548,6 +548,7 @@ $(BUILDDIR)/$(gcc_ver)/Makefile \
|
||||
$(PATHPRE) $(ENVS) $(GCC_CFG) $(EXTRA_CFLAGS) \
|
||||
$(CONFIG) \
|
||||
--with-sysroot=$(SYSROOT) \
|
||||
--with-debug-prefix-map=$(OUTPUT_ROOT)=devkit \
|
||||
--enable-languages=c,c++ \
|
||||
--enable-shared \
|
||||
--disable-nls \
|
||||
|
||||
@@ -48,7 +48,7 @@ $(eval $(call IncludeCustomExtension, hotspot/gensrc/GenerateSources.gmk))
|
||||
|
||||
# Setup the hotspot launcher script for developer use
|
||||
$(eval $(call SetupTextFileProcessing, CREATE_HOTSPOT_LAUNCHER, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/scripts/hotspot.sh, \
|
||||
SOURCE_FILES := $(TOPDIR)/make/scripts/hotspot.sh.template, \
|
||||
OUTPUT_FILE := $(JVM_OUTPUTDIR)/hotspot, \
|
||||
REPLACEMENTS := \
|
||||
@@LIBARCH@@ => $(OPENJDK_TARGET_CPU_LEGACY_LIB) ; \
|
||||
|
||||
@@ -85,7 +85,7 @@ CFLAGS_VM_VERSION := \
|
||||
|
||||
DISABLED_WARNINGS_gcc := array-bounds comment delete-non-virtual-dtor \
|
||||
empty-body implicit-fallthrough int-in-bool-context \
|
||||
maybe-uninitialized missing-field-initializers parentheses \
|
||||
maybe-uninitialized missing-field-initializers \
|
||||
shift-negative-value unknown-pragmas
|
||||
|
||||
DISABLED_WARNINGS_clang := sometimes-uninitialized \
|
||||
|
||||
@@ -48,9 +48,6 @@ ifneq ($(FDLIBM_CFLAGS), )
|
||||
endif
|
||||
|
||||
ifeq ($(call isTargetOs, linux), true)
|
||||
BUILD_LIBJVM_ostream.cpp_CXXFLAGS := -D_FILE_OFFSET_BITS=64
|
||||
BUILD_LIBJVM_logFileOutput.cpp_CXXFLAGS := -D_FILE_OFFSET_BITS=64
|
||||
|
||||
BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := -DNO_PCH $(FDLIBM_CFLAGS) $(LIBJVM_FDLIBM_COPY_OPT_FLAG)
|
||||
BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := -DNO_PCH $(FDLIBM_CFLAGS) $(LIBJVM_FDLIBM_COPY_OPT_FLAG)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -1289,25 +1289,58 @@ public class CLDRConverter {
|
||||
*/
|
||||
private static void generateTZDBShortNamesMap() throws IOException {
|
||||
Files.walk(Path.of(tzDataDir), 1, FileVisitOption.FOLLOW_LINKS)
|
||||
.filter(p -> p.toFile().isFile())
|
||||
.filter(p -> p.toFile().isFile() && !p.endsWith("jdk11_backward"))
|
||||
.forEach(p -> {
|
||||
try {
|
||||
String zone = null;
|
||||
String rule = null;
|
||||
String format = null;
|
||||
boolean inVanguard = false;
|
||||
boolean inRearguard = false;
|
||||
for (var line : Files.readAllLines(p)) {
|
||||
if (line.contains("#STDOFF")) continue;
|
||||
// Interpret the line in rearguard mode so that STD/DST
|
||||
// correctly handles negative DST cases, such as "GMT/IST"
|
||||
// vs. "IST/GMT" case for Europe/Dublin
|
||||
if (inVanguard) {
|
||||
if (line.startsWith("# Rearguard")) {
|
||||
inVanguard = false;
|
||||
inRearguard = true;
|
||||
}
|
||||
continue;
|
||||
} else if (line.startsWith("# Vanguard")) {
|
||||
inVanguard = true;
|
||||
continue;
|
||||
}
|
||||
if (inRearguard) {
|
||||
if (line.startsWith("# End of rearguard")) {
|
||||
inRearguard = false;
|
||||
continue;
|
||||
} else {
|
||||
if (line.startsWith("#\t")) {
|
||||
line = line.substring(1); // omit #
|
||||
}
|
||||
}
|
||||
}
|
||||
if (line.isBlank() || line.matches("^[ \t]*#.*")) {
|
||||
// ignore blank/comment lines
|
||||
continue;
|
||||
}
|
||||
// remove comments in-line
|
||||
line = line.replaceAll("[ \t]*#.*", "");
|
||||
|
||||
// Zone line
|
||||
if (line.startsWith("Zone")) {
|
||||
if (zone != null) {
|
||||
tzdbShortNamesMap.put(zone, format + NBSP + rule);
|
||||
}
|
||||
var zl = line.split("[ \t]+", -1);
|
||||
zone = zl[1];
|
||||
rule = zl[3];
|
||||
format = zl[4];
|
||||
} else {
|
||||
if (zone != null) {
|
||||
if (line.isBlank()) {
|
||||
if (line.startsWith("Rule") ||
|
||||
line.startsWith("Link")) {
|
||||
tzdbShortNamesMap.put(zone, format + NBSP + rule);
|
||||
zone = null;
|
||||
rule = null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -32,6 +32,7 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
@@ -339,9 +340,15 @@ public class GenerateCurrencyData {
|
||||
validCurrencyCodes.substring(i * 7 + 3, i * 7 + 6));
|
||||
checkCurrencyCode(currencyCode);
|
||||
int tableEntry = mainTable[(currencyCode.charAt(0) - 'A') * A_TO_Z + (currencyCode.charAt(1) - 'A')];
|
||||
if (tableEntry == INVALID_COUNTRY_ENTRY ||
|
||||
(tableEntry & SPECIAL_CASE_COUNTRY_MASK) != 0 ||
|
||||
(tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) != (currencyCode.charAt(2) - 'A')) {
|
||||
|
||||
// Do not allow a future currency to be classified as an otherCurrency,
|
||||
// otherwise it will leak out into Currency:getAvailableCurrencies
|
||||
boolean futureCurrency = Arrays.asList(specialCaseNewCurrencies).contains(currencyCode);
|
||||
boolean simpleCurrency = (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) == (currencyCode.charAt(2) - 'A');
|
||||
|
||||
// If neither a simple currency, or one defined in the future
|
||||
// then the current currency is applicable to be added to the otherTable
|
||||
if (!futureCurrency && !simpleCurrency) {
|
||||
if (otherCurrenciesCount == maxOtherCurrencies) {
|
||||
throw new RuntimeException("too many other currencies");
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ ifeq ($(call isTargetOs, linux)+$(call isTargetCpu, x86_64)+$(INCLUDE_COMPILER2)
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
OPTIMIZATION := HIGH, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB), \
|
||||
CXXFLAGS := $(CXXFLAGS_JDKLIB), \
|
||||
CXXFLAGS := $(CXXFLAGS_JDKLIB) -std=c++17, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LIBS := $(LIBCXX), \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -47,7 +47,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBINSTRUMENT, \
|
||||
LDFLAGS_macosx := -L$(call FindLibDirForModule, java.base), \
|
||||
LDFLAGS_aix := -L$(SUPPORT_OUTPUTDIR)/native/java.base, \
|
||||
LIBS := $(JDKLIB_LIBS), \
|
||||
LIBS_unix := -ljava -ljvm $(LIBZ_LIBS), \
|
||||
LIBS_unix := $(LIBZ_LIBS), \
|
||||
LIBS_linux := -ljli $(LIBDL), \
|
||||
LIBS_aix := -liconv -ljli_static $(LIBDL), \
|
||||
LIBS_macosx := -ljli -liconv -framework Cocoa -framework Security \
|
||||
|
||||
@@ -53,11 +53,10 @@ JMH_UNPACKED_DIR := $(MICROBENCHMARK_OUTPUT)/jmh_jars
|
||||
JMH_UNPACKED_JARS_DONE := $(JMH_UNPACKED_DIR)/_unpacked.marker
|
||||
|
||||
# External dependencies
|
||||
JMH_COMPILE_JARS := $(JMH_CORE_JAR) $(JMH_GENERATOR_JAR)
|
||||
WHITEBOX_JAR := $(SUPPORT_OUTPUTDIR)/test/lib/wb.jar
|
||||
JMH_COMPILE_JARS := $(JMH_CORE_JAR) $(JMH_GENERATOR_JAR) $(WHITEBOX_JAR)
|
||||
JMH_RUNTIME_JARS := $(JMH_CORE_JAR) $(JMH_COMMONS_MATH_JAR) $(JMH_JOPT_SIMPLE_JAR)
|
||||
|
||||
MICROBENCHMARK_CLASSPATH := $(call PathList, $(JMH_COMPILE_JARS))
|
||||
|
||||
# Native dependencies
|
||||
MICROBENCHMARK_NATIVE_SRC_DIRS := $(MICROBENCHMARK_SRC)
|
||||
MICROBENCHMARK_NATIVE_OUTPUT := $(MICROBENCHMARK_OUTPUT)/native
|
||||
@@ -92,24 +91,29 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \
|
||||
$(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \
|
||||
TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \
|
||||
SMALL_JAVA := false, \
|
||||
CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \
|
||||
DISABLED_WARNINGS := restricted this-escape processing rawtypes cast serial preview, \
|
||||
CLASSPATH := $(JMH_COMPILE_JARS), \
|
||||
DISABLED_WARNINGS := restricted this-escape processing rawtypes cast \
|
||||
serial preview, \
|
||||
SRC := $(MICROBENCHMARK_SRC), \
|
||||
BIN := $(MICROBENCHMARK_CLASSES), \
|
||||
JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \
|
||||
--add-exports java.base/sun.invoke.util=ALL-UNNAMED \
|
||||
JAVAC_FLAGS := \
|
||||
--add-exports java.base/jdk.internal.classfile.impl=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.vm=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.event=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \
|
||||
--enable-preview \
|
||||
-processor org.openjdk.jmh.generators.BenchmarkProcessor, \
|
||||
JAVA_FLAGS := --add-modules jdk.unsupported --limit-modules java.management \
|
||||
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.vm=ALL-UNNAMED \
|
||||
--enable-preview, \
|
||||
--add-exports java.base/sun.invoke.util=ALL-UNNAMED \
|
||||
--add-exports java.base/sun.security.util=ALL-UNNAMED \
|
||||
--enable-preview \
|
||||
-XDsuppressNotes \
|
||||
-processor org.openjdk.jmh.generators.BenchmarkProcessor, \
|
||||
JAVA_FLAGS := \
|
||||
--add-exports java.base/jdk.internal.vm=ALL-UNNAMED \
|
||||
--add-modules jdk.unsupported \
|
||||
--enable-preview \
|
||||
--limit-modules java.management, \
|
||||
))
|
||||
|
||||
$(BUILD_JDK_MICROBENCHMARK): $(JMH_COMPILE_JARS)
|
||||
|
||||
@@ -23,12 +23,22 @@
|
||||
# questions.
|
||||
#
|
||||
|
||||
################################################################################
|
||||
# This file builds the Java components of testlib.
|
||||
# It also covers the test-image part, where the built files are copied to the
|
||||
# test image.
|
||||
################################################################################
|
||||
|
||||
default: all
|
||||
|
||||
include $(SPEC)
|
||||
include MakeBase.gmk
|
||||
include JavaCompilation.gmk
|
||||
|
||||
################################################################################
|
||||
# Targets for building the test lib jars
|
||||
################################################################################
|
||||
|
||||
TARGETS :=
|
||||
|
||||
TEST_LIB_SOURCE_DIR := $(TOPDIR)/test/lib
|
||||
@@ -63,8 +73,21 @@ $(eval $(call SetupJavaCompilation, BUILD_TEST_LIB_JAR, \
|
||||
|
||||
TARGETS += $(BUILD_TEST_LIB_JAR)
|
||||
|
||||
##########################################################################################
|
||||
build-test-lib: $(TARGETS)
|
||||
|
||||
all: $(TARGETS)
|
||||
################################################################################
|
||||
# Targets for building test-image.
|
||||
################################################################################
|
||||
|
||||
.PHONY: default all
|
||||
# Copy the jars to the test image.
|
||||
$(eval $(call SetupCopyFiles, COPY_LIBTEST_JARS, \
|
||||
DEST := $(TEST_IMAGE_DIR)/lib-test, \
|
||||
FILES := $(BUILD_WB_JAR_JAR) $(BUILD_TEST_LIB_JAR_JAR), \
|
||||
))
|
||||
#
|
||||
|
||||
test-image-lib: $(COPY_LIBTEST_JARS)
|
||||
|
||||
all: build-test-lib
|
||||
|
||||
.PHONY: default all build-test-lib test-image-lib
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -45,6 +45,10 @@ BUILD_LIBTEST_OUTPUT_DIR := $(OUTPUTDIR)/support/test/lib/native
|
||||
|
||||
BUILD_LIBTEST_IMAGE_DIR := $(TEST_IMAGE_DIR)/lib
|
||||
|
||||
ifeq ($(call isTargetOs, windows), false)
|
||||
BUILD_LIBTEST_LIBRARIES_EXCLUDE += libFileUtils.c
|
||||
endif
|
||||
|
||||
# This evaluation is expensive and should only be done if this target was
|
||||
# explicitly called.
|
||||
ifneq ($(filter build-test-lib-native, $(MAKECMDGOALS)), )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -857,6 +857,11 @@ else
|
||||
exeinvoke.c exestack-gap.c exestack-tls.c libAsyncGetCallTraceTest.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(call And, $(call isTargetOs, linux) $(call isTargetCpu, aarch64)), false)
|
||||
BUILD_HOTSPOT_JTREG_EXCLUDE += libTestSVEWithJNI.c
|
||||
endif
|
||||
|
||||
|
||||
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exesigtest := -ljvm
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -1716,7 +1716,7 @@ public class Intro extends JPanel {
|
||||
this.beginning = beg;
|
||||
this.ending = end;
|
||||
fm = surf.getMetrics(font);
|
||||
java.util.Arrays.sort(members);
|
||||
Arrays.sort(members);
|
||||
cast.add("CONTRIBUTORS");
|
||||
cast.add(" ");
|
||||
cast.addAll(Arrays.asList(members));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2014, 2021, Red Hat, Inc. All rights reserved.
|
||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
//
|
||||
@@ -8237,6 +8237,24 @@ instruct popCountL_mem(iRegINoSp dst, memory8 mem, vRegD tmp) %{
|
||||
ins_pipe(pipe_class_default);
|
||||
%}
|
||||
|
||||
// ============================================================================
|
||||
// VerifyVectorAlignment Instruction
|
||||
|
||||
instruct verify_vector_alignment(iRegP addr, immL_positive_bitmaskI mask, rFlagsReg cr) %{
|
||||
match(Set addr (VerifyVectorAlignment addr mask));
|
||||
effect(KILL cr);
|
||||
format %{ "verify_vector_alignment $addr $mask \t! verify alignment" %}
|
||||
ins_encode %{
|
||||
Label Lskip;
|
||||
// check if masked bits of addr are zero
|
||||
__ tst($addr$$Register, $mask$$constant);
|
||||
__ br(Assembler::EQ, Lskip);
|
||||
__ stop("verify_vector_alignment found a misaligned vector memory access");
|
||||
__ bind(Lskip);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
// ============================================================================
|
||||
// MemBar Instruction
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -282,7 +282,8 @@ void LIR_Assembler::osr_entry() {
|
||||
__ bind(L);
|
||||
}
|
||||
#endif
|
||||
__ ldp(r19, r20, Address(OSR_buf, slot_offset));
|
||||
__ ldr(r19, Address(OSR_buf, slot_offset));
|
||||
__ ldr(r20, Address(OSR_buf, slot_offset + BytesPerWord));
|
||||
__ str(r19, frame_map()->address_for_monitor_lock(i));
|
||||
__ str(r20, frame_map()->address_for_monitor_object(i));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -111,10 +111,10 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg, Register
|
||||
// Handle existing monitor.
|
||||
bind(object_has_monitor);
|
||||
|
||||
// The object's monitor m is unlocked iff m->owner == NULL,
|
||||
// The object's monitor m is unlocked iff m->owner == nullptr,
|
||||
// otherwise m->owner may contain a thread or a stack address.
|
||||
//
|
||||
// Try to CAS m->owner from NULL to current thread.
|
||||
// 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, tmp3Reg); // Sets flags for result
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "code/compiledIC.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
@@ -90,9 +91,9 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
address stub = find_stub();
|
||||
guarantee(stub != nullptr, "stub not found");
|
||||
|
||||
if (TraceICs) {
|
||||
{
|
||||
ResourceMark rm;
|
||||
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
p2i(instruction_address()),
|
||||
callee->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -58,7 +58,7 @@ static char* reserve_at_eor_compatible_address(size_t size, bool aslr) {
|
||||
0x7ffc, 0x7ffe, 0x7fff
|
||||
};
|
||||
static constexpr int num_immediates = sizeof(immediates) / sizeof(immediates[0]);
|
||||
const int start_index = aslr ? os::random() : 0;
|
||||
const int start_index = aslr ? os::next_random((int)os::javaTimeNanos()) : 0;
|
||||
constexpr int max_tries = 64;
|
||||
for (int ntry = 0; result == nullptr && ntry < max_tries; ntry ++) {
|
||||
// As in os::attempt_reserve_memory_between, we alternate between higher and lower
|
||||
|
||||
@@ -156,8 +156,6 @@
|
||||
static void verify_deopt_original_pc( CompiledMethod* nm, intptr_t* unextended_sp);
|
||||
#endif
|
||||
|
||||
const ImmutableOopMap* get_oop_map() const;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -195,7 +195,7 @@ inline bool frame::equal(frame other) const {
|
||||
&& unextended_sp() == other.unextended_sp()
|
||||
&& fp() == other.fp()
|
||||
&& pc() == other.pc();
|
||||
assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
|
||||
assert(!ret || (cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -359,20 +359,6 @@ inline int frame::sender_sp_ret_address_offset() {
|
||||
return frame::sender_sp_offset - frame::return_addr_offset;
|
||||
}
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
if (_cb == nullptr) return nullptr;
|
||||
if (_cb->oop_maps() != nullptr) {
|
||||
NativePostCallNop* nop = nativePostCallNop_at(_pc);
|
||||
if (nop != nullptr && nop->displacement() != 0) {
|
||||
int slot = ((nop->displacement() >> 24) & 0xff);
|
||||
return _cb->oop_map_for_slot(slot, _pc);
|
||||
}
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::sender
|
||||
inline frame frame::sender(RegisterMap* map) const {
|
||||
|
||||
@@ -42,8 +42,12 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
// and Operational Models for ARMv8"
|
||||
#define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
// According to the ARMv8 ARM, "Concurrent modification and execution
|
||||
// of instructions can lead to the resulting instruction performing
|
||||
// any behavior that can be achieved by executing any sequence of
|
||||
|
||||
@@ -193,4 +193,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Is SIMD sort supported for this CPU?
|
||||
static bool supports_simd_sort(BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // CPU_AARCH64_MATCHER_AARCH64_HPP
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/compiledIC.hpp"
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "nativeInst_aarch64.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/handles.hpp"
|
||||
@@ -189,8 +188,6 @@ void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) {
|
||||
CompiledICLocker::is_safe(addr_at(0)),
|
||||
"concurrent code patching");
|
||||
|
||||
ResourceMark rm;
|
||||
int code_size = NativeInstruction::instruction_size;
|
||||
address addr_call = addr_at(0);
|
||||
bool reachable = Assembler::reachable_from_branch_at(addr_call, dest);
|
||||
assert(NativeCall::is_call_at(addr_call), "unexpected code at call site");
|
||||
@@ -560,18 +557,23 @@ static bool is_movk_to_zr(uint32_t insn) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void NativePostCallNop::patch(jint diff) {
|
||||
bool NativePostCallNop::patch(int32_t oopmap_slot, int32_t cb_offset) {
|
||||
if (((oopmap_slot & 0xff) != oopmap_slot) || ((cb_offset & 0xffffff) != cb_offset)) {
|
||||
return false; // cannot encode
|
||||
}
|
||||
uint32_t data = ((uint32_t)oopmap_slot << 24) | cb_offset;
|
||||
#ifdef ASSERT
|
||||
assert(diff != 0, "must be");
|
||||
assert(data != 0, "must be");
|
||||
uint32_t insn1 = uint_at(4);
|
||||
uint32_t insn2 = uint_at(8);
|
||||
assert (is_movk_to_zr(insn1) && is_movk_to_zr(insn2), "must be");
|
||||
#endif
|
||||
|
||||
uint32_t lo = diff & 0xffff;
|
||||
uint32_t hi = (uint32_t)diff >> 16;
|
||||
uint32_t lo = data & 0xffff;
|
||||
uint32_t hi = data >> 16;
|
||||
Instruction_aarch64::patch(addr_at(4), 20, 5, lo);
|
||||
Instruction_aarch64::patch(addr_at(8), 20, 5, hi);
|
||||
return true; // successfully encoded
|
||||
}
|
||||
|
||||
void NativeDeoptInstruction::verify() {
|
||||
|
||||
@@ -691,16 +691,20 @@ public:
|
||||
return (insns & 0xffe0001fffffffff) == 0xf280001fd503201f;
|
||||
}
|
||||
|
||||
jint displacement() const {
|
||||
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const {
|
||||
uint64_t movk_insns = *(uint64_t*)addr_at(4);
|
||||
uint32_t lo = (movk_insns >> 5) & 0xffff;
|
||||
uint32_t hi = (movk_insns >> (5 + 32)) & 0xffff;
|
||||
uint32_t result = (hi << 16) | lo;
|
||||
|
||||
return (jint)result;
|
||||
uint32_t data = (hi << 16) | lo;
|
||||
if (data == 0) {
|
||||
return false; // no information encoded
|
||||
}
|
||||
cb_offset = (data & 0xffffff);
|
||||
oopmap_slot = (data >> 24) & 0xff;
|
||||
return true; // decoding succeeded
|
||||
}
|
||||
|
||||
void patch(jint diff);
|
||||
bool patch(int32_t oopmap_slot, int32_t cb_offset);
|
||||
void make_deopt();
|
||||
};
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
|
||||
uint int_args = 0;
|
||||
uint fp_args = 0;
|
||||
uint stk_args = 0; // inc by 2 each time
|
||||
uint stk_args = 0;
|
||||
|
||||
for (int i = 0; i < total_args_passed; i++) {
|
||||
switch (sig_bt[i]) {
|
||||
@@ -322,8 +322,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (int_args < Argument::n_int_register_parameters_j) {
|
||||
regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set1(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
stk_args += 1;
|
||||
}
|
||||
break;
|
||||
case T_VOID:
|
||||
@@ -340,6 +341,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (int_args < Argument::n_int_register_parameters_j) {
|
||||
regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set2(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
}
|
||||
@@ -348,8 +350,9 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (fp_args < Argument::n_float_register_parameters_j) {
|
||||
regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set1(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
stk_args += 1;
|
||||
}
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
@@ -357,6 +360,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
if (fp_args < Argument::n_float_register_parameters_j) {
|
||||
regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg());
|
||||
} else {
|
||||
stk_args = align_up(stk_args, 2);
|
||||
regs[i].set2(VMRegImpl::stack2reg(stk_args));
|
||||
stk_args += 2;
|
||||
}
|
||||
@@ -367,7 +371,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
}
|
||||
|
||||
return align_up(stk_args, 2);
|
||||
return stk_args;
|
||||
}
|
||||
|
||||
// Patch the callers callsite with entry to compiled code if it exists.
|
||||
|
||||
@@ -3603,11 +3603,9 @@ void TemplateTable::_new() {
|
||||
// get InstanceKlass
|
||||
__ load_resolved_klass_at_offset(r4, r3, r4, rscratch1);
|
||||
|
||||
// make sure klass is initialized & doesn't have finalizer
|
||||
// make sure klass is fully initialized
|
||||
__ ldrb(rscratch1, Address(r4, InstanceKlass::init_state_offset()));
|
||||
__ cmp(rscratch1, (u1)InstanceKlass::fully_initialized);
|
||||
__ br(Assembler::NE, slow_case);
|
||||
// make sure klass is initialized
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "Optimization requires support for fast class initialization checks");
|
||||
__ clinit_barrier(r4, rscratch1, nullptr /*L_fast_path*/, &slow_case);
|
||||
|
||||
// get instance_size in InstanceKlass (scaled to a count of bytes)
|
||||
__ ldrw(r3,
|
||||
|
||||
@@ -165,6 +165,7 @@ enum Ampere_CPU_Model {
|
||||
static int dcache_line_size() { return _dcache_line_size; }
|
||||
static int get_initial_sve_vector_length() { return _initial_sve_vector_length; };
|
||||
|
||||
// Aarch64 supports fast class initialization checks
|
||||
static bool supports_fast_class_init_checks() { return true; }
|
||||
constexpr static bool supports_stack_watermark_barrier() { return true; }
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
|
||||
temp_reg, temp_reg2, itable_index, L_no_such_interface);
|
||||
|
||||
// Reduce "estimate" such that "padding" does not drop below 8.
|
||||
const ptrdiff_t estimate = 124;
|
||||
const ptrdiff_t estimate = 144;
|
||||
const ptrdiff_t codesize = __ pc() - start_pc;
|
||||
slop_delta = (int)(estimate - codesize);
|
||||
slop_bytes += slop_delta;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
//
|
||||
// This code is free software; you can redistribute it and/or modify it
|
||||
@@ -9193,7 +9193,7 @@ instruct clear_array(iRegX cnt, iRegP base, iRegI temp, iRegX zero, Universe dum
|
||||
ins_encode %{
|
||||
__ mov($zero$$Register, 0);
|
||||
__ mov($temp$$Register, $cnt$$Register);
|
||||
Label(loop);
|
||||
Label loop;
|
||||
__ bind(loop);
|
||||
__ subs($temp$$Register, $temp$$Register, 4);
|
||||
__ str($zero$$Register, Address($base$$Register, $temp$$Register), ge);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -175,7 +175,7 @@ class Address {
|
||||
if (_index == noreg) {
|
||||
assert(-256 < _disp && _disp < 256, "encoding constraint");
|
||||
return _mode | up(_disp) << 23 | 1 << 22 | _base->encoding() << 16 |
|
||||
(abs(_disp) & 0xf0) << 4 | abs(_disp) & 0x0f;
|
||||
(abs(_disp) & 0xf0) << 4 | (abs(_disp) & 0x0f);
|
||||
} else {
|
||||
assert(_index != PC && (_mode == basic_offset || _index != _base), "unpredictable instruction");
|
||||
assert(_disp == 0 && _shift == lsl && _shift_imm == 0, "encoding constraint");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -2640,8 +2640,8 @@ void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* arg
|
||||
|
||||
|
||||
void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {
|
||||
assert(src->is_double_cpu() && dest->is_address() ||
|
||||
src->is_address() && dest->is_double_cpu(),
|
||||
assert((src->is_double_cpu() && dest->is_address()) ||
|
||||
(src->is_address() && dest->is_double_cpu()),
|
||||
"Simple move_op is called for all other cases");
|
||||
|
||||
int null_check_offset;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/nativeInst.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
@@ -105,9 +106,9 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
address stub = find_stub();
|
||||
guarantee(stub != nullptr, "stub not found");
|
||||
|
||||
if (TraceICs) {
|
||||
{
|
||||
ResourceMark rm;
|
||||
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
p2i(instruction_address()),
|
||||
callee->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
@@ -99,8 +99,6 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
const ImmutableOopMap* get_oop_map() const;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -93,7 +93,7 @@ inline bool frame::equal(frame other) const {
|
||||
&& unextended_sp() == other.unextended_sp()
|
||||
&& fp() == other.fp()
|
||||
&& pc() == other.pc();
|
||||
assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
|
||||
assert(!ret || (cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -218,20 +218,6 @@ inline int frame::frame_size() const {
|
||||
return sender_sp() - sp();
|
||||
}
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
if (_cb == nullptr) return nullptr;
|
||||
if (_cb->oop_maps() != nullptr) {
|
||||
NativePostCallNop* nop = nativePostCallNop_at(_pc);
|
||||
if (nop != nullptr && nop->displacement() != 0) {
|
||||
int slot = ((nop->displacement() >> 24) & 0xff);
|
||||
return _cb->oop_map_for_slot(slot, _pc);
|
||||
}
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline int frame::compiled_frame_stack_argsize() const {
|
||||
Unimplemented();
|
||||
return 0;
|
||||
|
||||
@@ -49,8 +49,12 @@ const bool HaveVFP = true;
|
||||
// arm32 is not specified as multi-copy-atomic
|
||||
// So we must not #define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#define STUBROUTINES_MD_HPP "stubRoutines_arm.hpp"
|
||||
#define INTERP_MASM_MD_HPP "interp_masm_arm.hpp"
|
||||
#define TEMPLATETABLE_MD_HPP "templateTable_arm.hpp"
|
||||
|
||||
@@ -303,15 +303,19 @@ void InterpreterMacroAssembler::load_field_entry(Register cache, Register index,
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::load_method_entry(Register cache, Register index, int bcp_offset) {
|
||||
assert_different_registers(cache, index);
|
||||
|
||||
// Get index out of bytecode pointer
|
||||
get_index_at_bcp(index, bcp_offset, cache /* as tmp */, sizeof(u2));
|
||||
|
||||
// sizeof(ResolvedMethodEntry) is not a power of 2 on Arm, so can't use shift
|
||||
mov(cache, sizeof(ResolvedMethodEntry));
|
||||
mul(index, index, cache); // Scale the index to be the entry index * sizeof(ResolvedMethodEntry)
|
||||
|
||||
// load constant pool cache pointer
|
||||
ldr(cache, Address(FP, frame::interpreter_frame_cache_offset * wordSize));
|
||||
// Get address of method entries array
|
||||
ldr(cache, Address(cache, ConstantPoolCache::method_entries_offset()));
|
||||
ldr(cache, Address(cache, in_bytes(ConstantPoolCache::method_entries_offset())));
|
||||
add(cache, cache, Array<ResolvedMethodEntry>::base_offset_in_bytes());
|
||||
add(cache, cache, index);
|
||||
}
|
||||
|
||||
@@ -186,4 +186,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Is SIMD sort supported for this CPU?
|
||||
static bool supports_simd_sort(BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // CPU_ARM_MATCHER_ARM_HPP
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -162,7 +162,7 @@ void NativeMovConstReg::set_data(intptr_t x, address pc) {
|
||||
unsigned int hi = (unsigned int)(x >> 16);
|
||||
this->set_encoding((this->encoding() & 0xfff0f000) | (lo & 0xf000) << 4 | (lo & 0xfff));
|
||||
next->set_encoding((next->encoding() & 0xfff0f000) | (hi & 0xf000) << 4 | (hi & 0xfff));
|
||||
} else if (oop_addr == nullptr & metadata_addr == nullptr) {
|
||||
} else if (oop_addr == nullptr && metadata_addr == nullptr) {
|
||||
// A static ldr_literal (without oop or metadata relocation)
|
||||
assert(is_ldr_literal(), "must be");
|
||||
int offset = ldr_offset();
|
||||
@@ -341,10 +341,6 @@ void NativePostCallNop::make_deopt() {
|
||||
NativeDeoptInstruction::insert(addr_at(0));
|
||||
}
|
||||
|
||||
void NativePostCallNop::patch(jint diff) {
|
||||
// unsupported for now
|
||||
}
|
||||
|
||||
void NativeDeoptInstruction::verify() {
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -396,7 +396,7 @@ class NativeMovConstReg: public NativeInstruction {
|
||||
inline NativeMovConstReg* nativeMovConstReg_at(address address) {
|
||||
NativeInstruction* ni = nativeInstruction_at(address);
|
||||
assert(ni->is_ldr_literal() || ni->is_pc_rel() ||
|
||||
ni->is_movw() && VM_Version::supports_movw(), "must be");
|
||||
(ni->is_movw() && VM_Version::supports_movw()), "must be");
|
||||
return (NativeMovConstReg*)address;
|
||||
}
|
||||
|
||||
@@ -438,8 +438,8 @@ inline NativeCall* nativeCall_before(address return_address) {
|
||||
class NativePostCallNop: public NativeInstruction {
|
||||
public:
|
||||
bool check() const { return is_nop(); }
|
||||
int displacement() const { return 0; }
|
||||
void patch(jint diff);
|
||||
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const { return false; }
|
||||
bool patch(int32_t oopmap_slot, int32_t cb_offset) { return false; }
|
||||
void make_deopt();
|
||||
};
|
||||
|
||||
|
||||
@@ -441,7 +441,6 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
}
|
||||
}
|
||||
|
||||
if (slot & 1) slot++;
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
||||
@@ -370,17 +370,16 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
if (index_size == sizeof(u4)) {
|
||||
__ load_resolved_indy_entry(Rcache, Rindex);
|
||||
__ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedIndyEntry::num_parameters_offset())));
|
||||
__ check_stack_top();
|
||||
__ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize));
|
||||
} else {
|
||||
// Pop N words from the stack
|
||||
assert(index_size == sizeof(u2), "Can only be u2");
|
||||
__ load_method_entry(Rcache, Rindex);
|
||||
__ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedIndyEntry::num_parameters_offset())));
|
||||
__ check_stack_top();
|
||||
__ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize));
|
||||
__ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedMethodEntry::num_parameters_offset())));
|
||||
}
|
||||
|
||||
__ check_stack_top();
|
||||
__ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize));
|
||||
|
||||
__ convert_retval_to_tos(state);
|
||||
|
||||
__ check_and_handle_popframe();
|
||||
|
||||
@@ -3666,15 +3666,15 @@ void TemplateTable::prepare_invoke(Register Rcache, Register recv) {
|
||||
// load receiver if needed (after extra argument is pushed so parameter size is correct)
|
||||
if (load_receiver) {
|
||||
__ ldrh(recv, Address(Rcache, in_bytes(ResolvedMethodEntry::num_parameters_offset())));
|
||||
Address recv_addr = __ receiver_argument_address(Rstack_top, Rtemp, recv);
|
||||
__ ldr(recv, recv_addr);
|
||||
__ add(recv, Rstack_top, AsmOperand(recv, lsl, Interpreter::logStackElementSize));
|
||||
__ ldr(recv, Address(recv, -Interpreter::stackElementSize));
|
||||
__ verify_oop(recv);
|
||||
}
|
||||
|
||||
// load return address
|
||||
{ const address table = (address) Interpreter::invoke_return_entry_table_for(code);
|
||||
__ mov_slow(Rtemp, table);
|
||||
__ ldr(LR, Address::indexed_ptr(Rtemp, ret_type));
|
||||
__ mov_slow(LR, table);
|
||||
__ ldr(LR, Address::indexed_ptr(LR, ret_type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3744,10 +3744,13 @@ void TemplateTable::invokevirtual(int byte_no) {
|
||||
void TemplateTable::invokespecial(int byte_no) {
|
||||
transition(vtos, vtos);
|
||||
assert(byte_no == f1_byte, "use this argument");
|
||||
|
||||
const Register Rrecv = R2_tmp;
|
||||
load_resolved_method_entry_special_or_static(R2_tmp, // ResolvedMethodEntry*
|
||||
const Register Rflags = R3_tmp;
|
||||
|
||||
load_resolved_method_entry_special_or_static(Rrecv, // ResolvedMethodEntry*
|
||||
Rmethod, // Method*
|
||||
R3_tmp); // Flags
|
||||
Rflags); // Flags
|
||||
prepare_invoke(Rrecv, Rrecv);
|
||||
__ verify_oop(Rrecv);
|
||||
__ null_check(Rrecv, Rtemp);
|
||||
@@ -3760,12 +3763,16 @@ void TemplateTable::invokespecial(int byte_no) {
|
||||
void TemplateTable::invokestatic(int byte_no) {
|
||||
transition(vtos, vtos);
|
||||
assert(byte_no == f1_byte, "use this argument");
|
||||
load_resolved_method_entry_special_or_static(R2_tmp, // ResolvedMethodEntry*
|
||||
|
||||
const Register Rrecv = R2_tmp;
|
||||
const Register Rflags = R3_tmp;
|
||||
|
||||
load_resolved_method_entry_special_or_static(Rrecv, // ResolvedMethodEntry*
|
||||
Rmethod, // Method*
|
||||
R3_tmp); // Flags
|
||||
prepare_invoke(R2_tmp, R2_tmp);
|
||||
Rflags); // Flags
|
||||
prepare_invoke(Rrecv, Rrecv);
|
||||
// do the call
|
||||
__ profile_call(R2_tmp);
|
||||
__ profile_call(Rrecv);
|
||||
__ jump_from_interpreted(Rmethod);
|
||||
}
|
||||
|
||||
@@ -3788,10 +3795,10 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
const Register Rflags = R3_tmp;
|
||||
const Register Rklass = R2_tmp; // Note! Same register with Rrecv
|
||||
|
||||
load_resolved_method_entry_interface(R2_tmp, // ResolvedMethodEntry*
|
||||
R1_tmp, // Klass*
|
||||
load_resolved_method_entry_interface(Rrecv, // ResolvedMethodEntry*
|
||||
Rinterf, // Klass*
|
||||
Rmethod, // Method* or itable/vtable index
|
||||
R3_tmp); // Flags
|
||||
Rflags); // Flags
|
||||
prepare_invoke(Rrecv, Rrecv);
|
||||
|
||||
// First check for Object case, then private interface method,
|
||||
|
||||
@@ -2862,6 +2862,7 @@ void LIR_Assembler::rt_call(LIR_Opr result, address dest,
|
||||
if (info != nullptr) {
|
||||
add_call_info_here(info);
|
||||
}
|
||||
assert(__ last_calls_return_pc() == __ pc(), "pcn not at return pc");
|
||||
__ post_call_nop();
|
||||
}
|
||||
|
||||
|
||||
@@ -167,9 +167,9 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
address stub = find_stub();
|
||||
guarantee(stub != nullptr, "stub not found");
|
||||
|
||||
if (TraceICs) {
|
||||
{
|
||||
ResourceMark rm;
|
||||
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
p2i(instruction_address()),
|
||||
callee->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ inline void Thaw<ConfigT>::patch_caller_links(intptr_t* sp, intptr_t* bottom) {
|
||||
if (is_entry_frame) {
|
||||
callers_sp = _cont.entryFP();
|
||||
} else {
|
||||
CodeBlob* cb = CodeCache::find_blob(pc);
|
||||
CodeBlob* cb = CodeCache::find_blob_fast(pc);
|
||||
callers_sp = sp + cb->frame_size();
|
||||
}
|
||||
// set the back link
|
||||
|
||||
@@ -136,7 +136,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
// It should be safe to construct the sender though it might not be valid.
|
||||
|
||||
frame sender(sender_sp, sender_pc);
|
||||
frame sender(sender_sp, sender_pc, nullptr /* unextended_sp */, nullptr /* fp */, sender_blob);
|
||||
|
||||
// Do we have a valid fp?
|
||||
address sender_fp = (address) sender.fp();
|
||||
@@ -196,12 +196,12 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const {
|
||||
assert(map->include_argument_oops(), "should be set by clear");
|
||||
|
||||
if (jfa->last_Java_pc() != nullptr) {
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_pc());
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_pc(), kind::code_blob);
|
||||
return fr;
|
||||
}
|
||||
// Last_java_pc is not set, if we come here from compiled code. The
|
||||
// constructor retrieves the PC from the stack.
|
||||
frame fr(jfa->last_Java_sp());
|
||||
frame fr(jfa->last_Java_sp(), nullptr, kind::code_blob);
|
||||
return fr;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ frame frame::sender_for_upcall_stub_frame(RegisterMap* map) const {
|
||||
assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
|
||||
map->clear();
|
||||
assert(map->include_argument_oops(), "should be set by clear");
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_pc());
|
||||
frame fr(jfa->last_Java_sp(), jfa->last_Java_pc(), kind::code_blob);
|
||||
|
||||
return fr;
|
||||
}
|
||||
@@ -451,7 +451,7 @@ intptr_t *frame::initial_deoptimization_info() {
|
||||
#ifndef PRODUCT
|
||||
// This is a generic constructor which is only used by pns() in debug.cpp.
|
||||
// fp is dropped and gets determined by backlink.
|
||||
frame::frame(void* sp, void* fp, void* pc) : frame((intptr_t*)sp, (address)pc) {}
|
||||
frame::frame(void* sp, void* fp, void* pc) : frame((intptr_t*)sp, (address)pc, kind::unknown) {}
|
||||
#endif
|
||||
|
||||
BasicObjectLock* frame::interpreter_frame_monitor_end() const {
|
||||
|
||||
@@ -393,18 +393,26 @@
|
||||
inline common_abi* own_abi() const { return (common_abi*) _sp; }
|
||||
inline common_abi* callers_abi() const { return (common_abi*) _fp; }
|
||||
|
||||
enum class kind {
|
||||
unknown, // The frame's pc is not necessarily in the CodeCache.
|
||||
// CodeCache::find_blob_fast(void* pc) can yield wrong results in this case and must not be used.
|
||||
code_blob, // The frame's pc is known to be in the CodeCache but it is likely not in an nmethod.
|
||||
// CodeCache::find_blob_fast() will be correct but not faster in this case.
|
||||
nmethod // This is likely the frame of a nmethod.
|
||||
// The code cache lookup is optimized based on NativePostCallNops.
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
// Initialize frame members (_pc and _sp must be given)
|
||||
inline void setup();
|
||||
inline void setup(kind knd);
|
||||
|
||||
public:
|
||||
|
||||
const ImmutableOopMap* get_oop_map() const;
|
||||
|
||||
// Constructors
|
||||
inline frame(intptr_t* sp, intptr_t* fp, address pc);
|
||||
inline frame(intptr_t* sp, address pc, intptr_t* unextended_sp = nullptr, intptr_t* fp = nullptr, CodeBlob* cb = nullptr);
|
||||
inline frame(intptr_t* sp, address pc, kind knd = kind::nmethod);
|
||||
inline frame(intptr_t* sp, address pc, intptr_t* unextended_sp, intptr_t* fp = nullptr, CodeBlob* cb = nullptr);
|
||||
inline frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map);
|
||||
inline frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map, bool on_heap);
|
||||
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
// Inline functions for ppc64 frames:
|
||||
|
||||
// Initialize frame members (_sp must be given)
|
||||
inline void frame::setup() {
|
||||
inline void frame::setup(kind knd) {
|
||||
if (_pc == nullptr) {
|
||||
_pc = (address)own_abi()->lr;
|
||||
assert(_pc != nullptr, "must have PC");
|
||||
}
|
||||
|
||||
if (_cb == nullptr) {
|
||||
_cb = CodeCache::find_blob(_pc);
|
||||
_cb = (knd == kind::nmethod) ? CodeCache::find_blob_fast(_pc) : CodeCache::find_blob(_pc);
|
||||
}
|
||||
|
||||
if (_unextended_sp == nullptr) {
|
||||
@@ -78,8 +78,8 @@ inline void frame::setup() {
|
||||
// Continuation frames on the java heap are not aligned.
|
||||
// When thawing interpreted frames the sp can be unaligned (see new_stack_frame()).
|
||||
assert(_on_heap ||
|
||||
(is_aligned(_sp, alignment_in_bytes) || is_interpreted_frame()) &&
|
||||
(is_aligned(_fp, alignment_in_bytes) || !is_fully_initialized()),
|
||||
((is_aligned(_sp, alignment_in_bytes) || is_interpreted_frame()) &&
|
||||
(is_aligned(_fp, alignment_in_bytes) || !is_fully_initialized())),
|
||||
"invalid alignment sp:" PTR_FORMAT " unextended_sp:" PTR_FORMAT " fp:" PTR_FORMAT, p2i(_sp), p2i(_unextended_sp), p2i(_fp));
|
||||
}
|
||||
|
||||
@@ -89,21 +89,27 @@ inline void frame::setup() {
|
||||
inline frame::frame() : _sp(nullptr), _pc(nullptr), _cb(nullptr), _oop_map(nullptr), _deopt_state(unknown),
|
||||
_on_heap(false), DEBUG_ONLY(_frame_index(-1) COMMA) _unextended_sp(nullptr), _fp(nullptr) {}
|
||||
|
||||
inline frame::frame(intptr_t* sp) : frame(sp, nullptr) {}
|
||||
inline frame::frame(intptr_t* sp) : frame(sp, nullptr, kind::nmethod) {}
|
||||
|
||||
inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) : frame(sp, pc, nullptr, fp, nullptr) {}
|
||||
|
||||
inline frame::frame(intptr_t* sp, address pc, kind knd)
|
||||
: _sp(sp), _pc(pc), _cb(nullptr), _oop_map(nullptr),
|
||||
_on_heap(false), DEBUG_ONLY(_frame_index(-1) COMMA) _unextended_sp(sp), _fp(nullptr) {
|
||||
setup(knd);
|
||||
}
|
||||
|
||||
inline frame::frame(intptr_t* sp, address pc, intptr_t* unextended_sp, intptr_t* fp, CodeBlob* cb)
|
||||
: _sp(sp), _pc(pc), _cb(cb), _oop_map(nullptr),
|
||||
_on_heap(false), DEBUG_ONLY(_frame_index(-1) COMMA) _unextended_sp(unextended_sp), _fp(fp) {
|
||||
setup();
|
||||
setup(kind::nmethod);
|
||||
}
|
||||
|
||||
inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map)
|
||||
: _sp(sp), _pc(pc), _cb(cb), _oop_map(oop_map),
|
||||
_on_heap(false), DEBUG_ONLY(_frame_index(-1) COMMA) _unextended_sp(unextended_sp), _fp(fp) {
|
||||
assert(_cb != nullptr, "pc: " INTPTR_FORMAT, p2i(pc));
|
||||
setup();
|
||||
setup(kind::nmethod);
|
||||
}
|
||||
|
||||
inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb,
|
||||
@@ -113,7 +119,7 @@ inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address
|
||||
// In thaw, non-heap frames use this constructor to pass oop_map. I don't know why.
|
||||
assert(_on_heap || _cb != nullptr, "these frames are always heap frames");
|
||||
if (cb != nullptr) {
|
||||
setup();
|
||||
setup(kind::nmethod);
|
||||
}
|
||||
#ifdef ASSERT
|
||||
// The following assertion has been disabled because it would sometime trap for Continuation.run,
|
||||
@@ -300,7 +306,7 @@ inline frame frame::sender_raw(RegisterMap* map) const {
|
||||
|
||||
// Must be native-compiled frame, i.e. the marshaling code for native
|
||||
// methods that exists in the core system.
|
||||
return frame(sender_sp(), sender_pc());
|
||||
return frame(sender_sp(), sender_pc(), kind::code_blob);
|
||||
}
|
||||
|
||||
inline frame frame::sender(RegisterMap* map) const {
|
||||
@@ -361,20 +367,6 @@ inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
|
||||
*result_adr = obj;
|
||||
}
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
if (_cb == nullptr) return nullptr;
|
||||
if (_cb->oop_maps() != nullptr) {
|
||||
NativePostCallNop* nop = nativePostCallNop_at(_pc);
|
||||
if (nop != nullptr && nop->displacement() != 0) {
|
||||
int slot = ((nop->displacement() >> 24) & 0xff);
|
||||
return _cb->oop_map_for_slot(slot, _pc);
|
||||
}
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline int frame::compiled_frame_stack_argsize() const {
|
||||
assert(cb()->is_compiled(), "");
|
||||
return (cb()->as_compiled_method()->method()->num_stack_arg_slots() * VMRegImpl::stack_slot_size) >> LogBytesPerWord;
|
||||
|
||||
@@ -23,11 +23,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "gc/shared/gcArguments.hpp"
|
||||
#include "gc/shared/gc_globals.hpp"
|
||||
#include "macroAssembler_ppc.hpp"
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "gc/shared/gcArguments.hpp"
|
||||
#include "gc/shared/gc_globals.hpp"
|
||||
#include "gc/shenandoah/shenandoahBarrierSet.hpp"
|
||||
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
|
||||
#include "gc/shenandoah/shenandoahForwarding.hpp"
|
||||
@@ -38,6 +37,7 @@
|
||||
#include "gc/shenandoah/shenandoahThreadLocalData.hpp"
|
||||
#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "macroAssembler_ppc.hpp"
|
||||
#include "runtime/javaThread.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include "asm/register.hpp"
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/register.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "code/codeBlob.hpp"
|
||||
#include "code/vmreg.inline.hpp"
|
||||
|
||||
@@ -48,9 +48,12 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||
// PPC64 is not specified as multi-copy-atomic
|
||||
// So we must not #define CPU_MULTI_COPY_ATOMIC
|
||||
|
||||
// The expected size in bytes of a cache line, used to pad data structures.
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 128
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#define SUPPORT_RESERVED_STACK_AREA
|
||||
|
||||
// If UseSIGTRAP is active, we only use the poll bit and no polling page.
|
||||
|
||||
@@ -1187,8 +1187,12 @@ void MacroAssembler::post_call_nop() {
|
||||
if (!Continuations::enabled()) {
|
||||
return;
|
||||
}
|
||||
// We use CMPI/CMPLI instructions to encode post call nops.
|
||||
// Refer to NativePostCallNop for details.
|
||||
relocate(post_call_nop_Relocation::spec());
|
||||
InlineSkippedInstructionsCounter skipCounter(this);
|
||||
nop();
|
||||
Assembler::emit_int32(Assembler::CMPLI_OPCODE | Assembler::opp_u_field(1, 9, 9));
|
||||
assert(is_post_call_nop(*(int*)(pc() - 4)), "post call not not found");
|
||||
}
|
||||
|
||||
void MacroAssembler::call_VM_base(Register oop_result,
|
||||
|
||||
@@ -417,6 +417,12 @@ class MacroAssembler: public Assembler {
|
||||
inline void call_stub_and_return_to(Register function_entry, Register return_pc);
|
||||
|
||||
void post_call_nop();
|
||||
static bool is_post_call_nop(int instr_bits) {
|
||||
const uint32_t nineth_bit = opp_u_field(1, 9, 9);
|
||||
const uint32_t opcode_mask = 0b111110 << OPCODE_SHIFT;
|
||||
const uint32_t pcn_mask = opcode_mask | nineth_bit;
|
||||
return (instr_bits & pcn_mask) == (Assembler::CMPLI_OPCODE | nineth_bit);
|
||||
}
|
||||
|
||||
//
|
||||
// Java utilities
|
||||
|
||||
@@ -195,4 +195,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Is SIMD sort supported for this CPU?
|
||||
static bool supports_simd_sort(BasicType bt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // CPU_PPC_MATCHER_PPC_HPP
|
||||
|
||||
@@ -429,8 +429,29 @@ void NativePostCallNop::make_deopt() {
|
||||
NativeDeoptInstruction::insert(addr_at(0));
|
||||
}
|
||||
|
||||
void NativePostCallNop::patch(jint diff) {
|
||||
// unsupported for now
|
||||
bool NativePostCallNop::patch(int32_t oopmap_slot, int32_t cb_offset) {
|
||||
int32_t i2, i1;
|
||||
assert(is_aligned(cb_offset, 4), "cb offset alignment does not match instruction alignment");
|
||||
assert(!decode(i1, i2), "already patched");
|
||||
|
||||
cb_offset = cb_offset >> 2;
|
||||
if (((oopmap_slot & ppc_oopmap_slot_mask) != oopmap_slot) || ((cb_offset & ppc_cb_offset_mask) != cb_offset)) {
|
||||
return false; // cannot encode
|
||||
}
|
||||
const uint32_t data = oopmap_slot << ppc_cb_offset_bits | cb_offset;
|
||||
const uint32_t lo_data = data & ppc_data_lo_mask;
|
||||
const uint32_t hi_data = data >> ppc_data_lo_bits;
|
||||
const uint32_t nineth_bit = 1 << (31 - 9);
|
||||
uint32_t instr = Assembler::CMPLI_OPCODE | hi_data << ppc_data_hi_shift | nineth_bit | lo_data;
|
||||
*(uint32_t*)addr_at(0) = instr;
|
||||
|
||||
int32_t oopmap_slot_dec, cb_offset_dec;
|
||||
assert(is_post_call_nop(), "pcn not recognized");
|
||||
assert(decode(oopmap_slot_dec, cb_offset_dec), "encoding failed");
|
||||
assert(oopmap_slot == oopmap_slot_dec, "oopmap slot encoding is wrong");
|
||||
assert((cb_offset << 2) == cb_offset_dec, "cb offset encoding is wrong");
|
||||
|
||||
return true; // encoding succeeded
|
||||
}
|
||||
|
||||
void NativeDeoptInstruction::verify() {
|
||||
|
||||
@@ -51,7 +51,7 @@ class NativeInstruction {
|
||||
friend class Relocation;
|
||||
|
||||
public:
|
||||
bool is_nop() const { return Assembler::is_nop(long_at(0)); }
|
||||
bool is_post_call_nop() const { return MacroAssembler::is_post_call_nop(long_at(0)); }
|
||||
|
||||
bool is_jump() const { return Assembler::is_b(long_at(0)); } // See NativeGeneralJump.
|
||||
|
||||
@@ -506,10 +506,50 @@ class NativeMovRegMem: public NativeInstruction {
|
||||
};
|
||||
|
||||
class NativePostCallNop: public NativeInstruction {
|
||||
|
||||
// We use CMPI/CMPLI to represent Post Call Nops (PCN)
|
||||
|
||||
// Bit |0 5|6 |9 |10|11 |16 31|
|
||||
// +--------------------------------------------------------------+
|
||||
// Field |OPCODE |BF |/ |L |RA |SI |
|
||||
// +--------------------------------------------------------------+
|
||||
// |0 0 1 0 1|DATA HI| 1| DATA LO |
|
||||
// | |4 bits | | 22 bits |
|
||||
//
|
||||
// Bit 9 is always 1 for PCNs to distinguish them from regular CMPI/CMPLI
|
||||
//
|
||||
// Using both, CMPLI (opcode 10 = 0b001010) and CMPI (opcode 11 = 0b001011) for
|
||||
// PCNs allows using bit 5 from the opcode to encode DATA HI.
|
||||
|
||||
enum {
|
||||
ppc_data_lo_bits = 31 - 9,
|
||||
ppc_data_lo_mask = right_n_bits(ppc_data_lo_bits),
|
||||
ppc_data_hi_bits = 9 - 5,
|
||||
ppc_data_hi_shift = ppc_data_lo_bits + 1,
|
||||
ppc_data_hi_mask = right_n_bits(ppc_data_hi_bits) << ppc_data_hi_shift,
|
||||
ppc_data_bits = ppc_data_lo_bits + ppc_data_hi_bits,
|
||||
|
||||
ppc_oopmap_slot_bits = 9,
|
||||
ppc_oopmap_slot_mask = right_n_bits(ppc_oopmap_slot_bits),
|
||||
ppc_cb_offset_bits = ppc_data_bits - ppc_oopmap_slot_bits,
|
||||
ppc_cb_offset_mask = right_n_bits(ppc_cb_offset_bits),
|
||||
};
|
||||
|
||||
public:
|
||||
bool check() const { return is_nop(); }
|
||||
int displacement() const { return 0; }
|
||||
void patch(jint diff);
|
||||
bool check() const { return is_post_call_nop(); }
|
||||
bool decode(int32_t& oopmap_slot, int32_t& cb_offset) const {
|
||||
uint32_t instr_bits = long_at(0);
|
||||
uint32_t data_lo = instr_bits & ppc_data_lo_mask;
|
||||
uint32_t data_hi = (instr_bits & ppc_data_hi_mask) >> 1;
|
||||
uint32_t data = data_hi | data_lo;
|
||||
if (data == 0) {
|
||||
return false; // no data found
|
||||
}
|
||||
cb_offset = (data & ppc_cb_offset_mask) << 2;
|
||||
oopmap_slot = data >> ppc_cb_offset_bits;
|
||||
return true; // decoding succeeded
|
||||
}
|
||||
bool patch(int32_t oopmap_slot, int32_t cb_offset);
|
||||
void make_deopt();
|
||||
};
|
||||
|
||||
|
||||
@@ -734,7 +734,7 @@ int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
return align_up(stk, 2);
|
||||
return stk;
|
||||
}
|
||||
|
||||
#if defined(COMPILER1) || defined(COMPILER2)
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
// Override Abstract_VM_Version implementation
|
||||
static void print_platform_virtualization_info(outputStream*);
|
||||
|
||||
// PPC64 supports fast class initialization checks for static methods.
|
||||
// PPC64 supports fast class initialization checks
|
||||
static bool supports_fast_class_init_checks() { return true; }
|
||||
constexpr static bool supports_stack_watermark_barrier() { return true; }
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@@ -506,7 +506,7 @@ public:
|
||||
INSN(sllw, 0b0111011, 0b001, 0b0000000);
|
||||
INSN(sraw, 0b0111011, 0b101, 0b0100000);
|
||||
INSN(srlw, 0b0111011, 0b101, 0b0000000);
|
||||
INSN(mul, 0b0110011, 0b000, 0b0000001);
|
||||
INSN(_mul, 0b0110011, 0b000, 0b0000001);
|
||||
INSN(mulh, 0b0110011, 0b001, 0b0000001);
|
||||
INSN(mulhsu,0b0110011, 0b010, 0b0000001);
|
||||
INSN(mulhu, 0b0110011, 0b011, 0b0000001);
|
||||
@@ -537,9 +537,9 @@ public:
|
||||
}
|
||||
|
||||
INSN(lb, 0b0000011, 0b000);
|
||||
INSN(lbu, 0b0000011, 0b100);
|
||||
INSN(lh, 0b0000011, 0b001);
|
||||
INSN(lhu, 0b0000011, 0b101);
|
||||
INSN(_lbu, 0b0000011, 0b100);
|
||||
INSN(_lh, 0b0000011, 0b001);
|
||||
INSN(_lhu, 0b0000011, 0b101);
|
||||
INSN(_lw, 0b0000011, 0b010);
|
||||
INSN(lwu, 0b0000011, 0b110);
|
||||
INSN(_ld, 0b0000011, 0b011);
|
||||
@@ -609,8 +609,8 @@ public:
|
||||
emit(insn); \
|
||||
} \
|
||||
|
||||
INSN(sb, Register, 0b0100011, 0b000);
|
||||
INSN(sh, Register, 0b0100011, 0b001);
|
||||
INSN(_sb, Register, 0b0100011, 0b000);
|
||||
INSN(_sh, Register, 0b0100011, 0b001);
|
||||
INSN(_sw, Register, 0b0100011, 0b010);
|
||||
INSN(_sd, Register, 0b0100011, 0b011);
|
||||
INSN(fsw, FloatRegister, 0b0100111, 0b010);
|
||||
@@ -758,6 +758,8 @@ enum Aqrl {relaxed = 0b00, rl = 0b01, aq = 0b10, aqrl = 0b11};
|
||||
INSN(amomax_d , 0b0101111, 0b011, 0b10100);
|
||||
INSN(amominu_d, 0b0101111, 0b011, 0b11000);
|
||||
INSN(amomaxu_d, 0b0101111, 0b011, 0b11100);
|
||||
INSN(amocas_w, 0b0101111, 0b010, 0b00101);
|
||||
INSN(amocas_d, 0b0101111, 0b011, 0b00101);
|
||||
#undef INSN
|
||||
|
||||
enum operand_size { int8, int16, int32, uint32, int64 };
|
||||
@@ -813,6 +815,8 @@ enum operand_size { int8, int16, int32, uint32, int64 };
|
||||
|
||||
INSN(fsqrt_s, 0b1010011, 0b00000, 0b0101100);
|
||||
INSN(fsqrt_d, 0b1010011, 0b00000, 0b0101101);
|
||||
INSN(fcvt_s_h, 0b1010011, 0b00010, 0b0100000);
|
||||
INSN(fcvt_h_s, 0b1010011, 0b00000, 0b0100010);
|
||||
INSN(fcvt_s_d, 0b1010011, 0b00001, 0b0100000);
|
||||
INSN(fcvt_d_s, 0b1010011, 0b00000, 0b0100001);
|
||||
#undef INSN
|
||||
@@ -1069,6 +1073,7 @@ enum operand_size { int8, int16, int32, uint32, int64 };
|
||||
emit(insn); \
|
||||
}
|
||||
|
||||
INSN(fmv_h_x, 0b1010011, 0b000, 0b00000, 0b1111010);
|
||||
INSN(fmv_w_x, 0b1010011, 0b000, 0b00000, 0b1111000);
|
||||
INSN(fmv_d_x, 0b1010011, 0b000, 0b00000, 0b1111001);
|
||||
|
||||
@@ -1106,8 +1111,10 @@ enum fclass_mask {
|
||||
emit(insn); \
|
||||
}
|
||||
|
||||
INSN(fclass_h, 0b1010011, 0b001, 0b00000, 0b1110010);
|
||||
INSN(fclass_s, 0b1010011, 0b001, 0b00000, 0b1110000);
|
||||
INSN(fclass_d, 0b1010011, 0b001, 0b00000, 0b1110001);
|
||||
INSN(fmv_x_h, 0b1010011, 0b000, 0b00000, 0b1110010);
|
||||
INSN(fmv_x_w, 0b1010011, 0b000, 0b00000, 0b1110000);
|
||||
INSN(fmv_x_d, 0b1010011, 0b000, 0b00000, 0b1110001);
|
||||
|
||||
@@ -1154,10 +1161,8 @@ static Assembler::SEW elemtype_to_sew(BasicType etype) {
|
||||
}
|
||||
|
||||
#define patch_vtype(hsb, lsb, vlmul, vsew, vta, vma, vill) \
|
||||
if (vill == 1) { \
|
||||
guarantee((vlmul | vsew | vta | vma == 0), \
|
||||
"the other bits in vtype shall be zero"); \
|
||||
} \
|
||||
/* If vill then other bits of vtype must be zero. */ \
|
||||
guarantee(!vill, "vill not supported"); \
|
||||
patch((address)&insn, lsb + 2, lsb, vlmul); \
|
||||
patch((address)&insn, lsb + 5, lsb + 3, vsew); \
|
||||
patch((address)&insn, lsb + 6, vta); \
|
||||
@@ -1332,6 +1337,7 @@ enum VectorMask {
|
||||
INSN(vsll_vi, 0b1010111, 0b011, 0b100101);
|
||||
|
||||
// Vector Slide Instructions
|
||||
INSN(vslideup_vi, 0b1010111, 0b011, 0b001110);
|
||||
INSN(vslidedown_vi, 0b1010111, 0b011, 0b001111);
|
||||
|
||||
#undef INSN
|
||||
@@ -1687,7 +1693,6 @@ enum VectorMask {
|
||||
INSN(vmv_v_x, 0b1010111, 0b100, v0, 0b1, 0b010111);
|
||||
|
||||
#undef INSN
|
||||
#undef patch_VArith
|
||||
|
||||
#define INSN(NAME, op, funct13, funct6) \
|
||||
void NAME(VectorRegister Vd, VectorMask vm = unmasked) { \
|
||||
@@ -1729,14 +1734,29 @@ enum Nf {
|
||||
patch_reg((address)&insn, 15, Rs1); \
|
||||
emit(insn)
|
||||
|
||||
#define INSN(NAME, op, lumop, vm, mop, nf) \
|
||||
void NAME(VectorRegister Vd, Register Rs1, uint32_t width = 0, bool mew = false) { \
|
||||
#define INSN(NAME, op, width, lumop, vm, mop, mew, nf) \
|
||||
void NAME(VectorRegister Vd, Register Rs1) { \
|
||||
guarantee(is_uimm3(width), "width is invalid"); \
|
||||
patch_VLdSt(op, Vd, width, Rs1, lumop, vm, mop, mew, nf); \
|
||||
}
|
||||
|
||||
// Vector Load/Store Instructions
|
||||
INSN(vl1re8_v, 0b0000111, 0b01000, 0b1, 0b00, g1);
|
||||
INSN(vl1re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vl1re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vl1re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vl1re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vl2re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vl2re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vl2re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vl2re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vl4re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vl4re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vl4re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vl4re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vl8re8_v, 0b0000111, 0b000, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
INSN(vl8re16_v, 0b0000111, 0b101, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
INSN(vl8re32_v, 0b0000111, 0b110, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
INSN(vl8re64_v, 0b0000111, 0b111, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
|
||||
#undef INSN
|
||||
|
||||
@@ -1747,6 +1767,9 @@ enum Nf {
|
||||
|
||||
// Vector Load/Store Instructions
|
||||
INSN(vs1r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g1);
|
||||
INSN(vs2r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g2);
|
||||
INSN(vs4r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g4);
|
||||
INSN(vs8r_v, 0b0100111, 0b000, 0b01000, 0b1, 0b00, 0b0, g8);
|
||||
|
||||
#undef INSN
|
||||
|
||||
@@ -1792,9 +1815,11 @@ enum Nf {
|
||||
}
|
||||
|
||||
// Vector unordered indexed load instructions
|
||||
INSN( vluxei8_v, 0b0000111, 0b000, 0b01, 0b0);
|
||||
INSN(vluxei32_v, 0b0000111, 0b110, 0b01, 0b0);
|
||||
|
||||
// Vector unordered indexed store instructions
|
||||
INSN( vsuxei8_v, 0b0100111, 0b000, 0b01, 0b0);
|
||||
INSN(vsuxei32_v, 0b0100111, 0b110, 0b01, 0b0);
|
||||
|
||||
#undef INSN
|
||||
@@ -1818,6 +1843,55 @@ enum Nf {
|
||||
#undef INSN
|
||||
#undef patch_VLdSt
|
||||
|
||||
// ====================================
|
||||
// RISC-V Vector Crypto Extension
|
||||
// ====================================
|
||||
|
||||
#define INSN(NAME, op, funct3, funct6) \
|
||||
void NAME(VectorRegister Vd, VectorRegister Vs2, VectorRegister Vs1, VectorMask vm = unmasked) { \
|
||||
patch_VArith(op, Vd, funct3, Vs1->raw_encoding(), Vs2, vm, funct6); \
|
||||
}
|
||||
|
||||
// Vector Bit-manipulation used in Cryptography (Zvkb) Extension
|
||||
INSN(vandn_vv, 0b1010111, 0b000, 0b000001);
|
||||
INSN(vandn_vx, 0b1010111, 0b100, 0b000001);
|
||||
INSN(vandn_vi, 0b1010111, 0b011, 0b000001);
|
||||
INSN(vclmul_vv, 0b1010111, 0b010, 0b001100);
|
||||
INSN(vclmul_vx, 0b1010111, 0b110, 0b001100);
|
||||
INSN(vclmulh_vv, 0b1010111, 0b010, 0b001101);
|
||||
INSN(vclmulh_vx, 0b1010111, 0b110, 0b001101);
|
||||
INSN(vror_vv, 0b1010111, 0b000, 0b010100);
|
||||
INSN(vror_vx, 0b1010111, 0b100, 0b010100);
|
||||
INSN(vrol_vv, 0b1010111, 0b000, 0b010101);
|
||||
INSN(vrol_vx, 0b1010111, 0b100, 0b010101);
|
||||
|
||||
#undef INSN
|
||||
|
||||
#define INSN(NAME, op, funct3, Vs1, funct6) \
|
||||
void NAME(VectorRegister Vd, VectorRegister Vs2, VectorMask vm = unmasked) { \
|
||||
patch_VArith(op, Vd, funct3, Vs1, Vs2, vm, funct6); \
|
||||
}
|
||||
|
||||
// Vector Bit-manipulation used in Cryptography (Zvkb) Extension
|
||||
INSN(vbrev8_v, 0b1010111, 0b010, 0b01000, 0b010010);
|
||||
INSN(vrev8_v, 0b1010111, 0b010, 0b01001, 0b010010);
|
||||
|
||||
#undef INSN
|
||||
|
||||
#define INSN(NAME, op, funct3, vm, funct6) \
|
||||
void NAME(VectorRegister Vd, VectorRegister Vs2, VectorRegister Vs1) { \
|
||||
patch_VArith(op, Vd, funct3, Vs1->raw_encoding(), Vs2, vm, funct6); \
|
||||
}
|
||||
|
||||
// Vector SHA-2 Secure Hash (Zvknh[ab]) Extension
|
||||
INSN(vsha2ms_vv, 0b1110111, 0b010, 0b1, 0b101101);
|
||||
INSN(vsha2ch_vv, 0b1110111, 0b010, 0b1, 0b101110);
|
||||
INSN(vsha2cl_vv, 0b1110111, 0b010, 0b1, 0b101111);
|
||||
|
||||
#undef INSN
|
||||
|
||||
#undef patch_VArith
|
||||
|
||||
// ====================================
|
||||
// RISC-V Bit-Manipulation Extension
|
||||
// Currently only support Zba, Zbb and Zbs bitmanip extensions.
|
||||
@@ -1867,9 +1941,9 @@ enum Nf {
|
||||
}
|
||||
|
||||
INSN(rev8, 0b0010011, 0b101, 0b011010111000);
|
||||
INSN(sext_b, 0b0010011, 0b001, 0b011000000100);
|
||||
INSN(sext_h, 0b0010011, 0b001, 0b011000000101);
|
||||
INSN(zext_h, 0b0111011, 0b100, 0b000010000000);
|
||||
INSN(_sext_b, 0b0010011, 0b001, 0b011000000100);
|
||||
INSN(_sext_h, 0b0010011, 0b001, 0b011000000101);
|
||||
INSN(_zext_h, 0b0111011, 0b100, 0b000010000000);
|
||||
INSN(clz, 0b0010011, 0b001, 0b011000000000);
|
||||
INSN(clzw, 0b0011011, 0b001, 0b011000000000);
|
||||
INSN(ctz, 0b0010011, 0b001, 0b011000000001);
|
||||
@@ -2581,6 +2655,15 @@ public:
|
||||
return UseRVC && in_compressible_region();
|
||||
}
|
||||
|
||||
bool do_compress_zcb(Register reg1 = noreg, Register reg2 = noreg) const {
|
||||
return do_compress() && VM_Version::ext_Zcb.enabled() &&
|
||||
(reg1 == noreg || reg1->is_compressed_valid()) && (reg2 == noreg || reg2->is_compressed_valid());
|
||||
}
|
||||
|
||||
bool do_compress_zcb_zbb(Register reg1 = noreg, Register reg2 = noreg) const {
|
||||
return do_compress_zcb(reg1, reg2) && UseZbb;
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
// Load/store register
|
||||
// --------------------------
|
||||
@@ -2915,6 +2998,238 @@ public:
|
||||
|
||||
#undef INSN
|
||||
|
||||
// -------------- ZCB Instruction Definitions --------------
|
||||
// Zcb additional C instructions
|
||||
private:
|
||||
// Format CLH, c.lh/c.lhu
|
||||
template <bool Unsigned>
|
||||
void c_lh_if(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
|
||||
assert_cond(uimm == 0 || uimm == 2);
|
||||
assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b00);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
|
||||
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
|
||||
c_patch((address)&insn, 6, 6, Unsigned ? 0 : 1);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b001);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
template <bool Unsigned>
|
||||
void lh_c_mux(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
|
||||
if (do_compress_zcb(Rd_Rs2, Rs1) &&
|
||||
(uimm == 0 || uimm == 2)) {
|
||||
c_lh_if<Unsigned>(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
if (Unsigned) {
|
||||
_lhu(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
_lh(Rd_Rs2, Rs1, uimm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format CU, c.[sz]ext.*, c.not
|
||||
template <uint8_t InstructionType>
|
||||
void c_u_if(Register Rs1) {
|
||||
assert_cond(do_compress_zcb(Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b01);
|
||||
c_patch((address)&insn, 4, 2, InstructionType);
|
||||
c_patch((address)&insn, 6, 5, 0b11);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b111);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Prerequisites: Zcb
|
||||
void c_lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_if<false>(Rd_Rs2, Rs1, uimm); }
|
||||
void lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_c_mux<false>(Rd_Rs2, Rs1, uimm); }
|
||||
|
||||
// Prerequisites: Zcb
|
||||
void c_lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_if<true>(Rd_Rs2, Rs1, uimm); }
|
||||
void lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_c_mux<true>(Rd_Rs2, Rs1, uimm); }
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CLB, single instruction
|
||||
void c_lbu(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
|
||||
assert_cond(uimm <= 3);
|
||||
assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b00);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
|
||||
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
|
||||
c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b000);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
void lbu(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
|
||||
if (do_compress_zcb(Rd_Rs2, Rs1) &&
|
||||
uimm >= 0 && uimm <= 3) {
|
||||
c_lbu(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
_lbu(Rd_Rs2, Rs1, uimm);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CSB, single instruction
|
||||
void c_sb(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
|
||||
assert_cond(uimm <= 3);
|
||||
assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b00);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
|
||||
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
|
||||
c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b010);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
void sb(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
|
||||
if (do_compress_zcb(Rd_Rs2, Rs1) &&
|
||||
uimm >= 0 && uimm <= 3) {
|
||||
c_sb(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
_sb(Rd_Rs2, Rs1, uimm);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CSH, single instruction
|
||||
void c_sh(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
|
||||
assert_cond(uimm == 0 || uimm == 2);
|
||||
assert_cond(do_compress_zcb(Rd_Rs2, Rs1));
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b00);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
|
||||
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
|
||||
c_patch((address)&insn, 6, 6, 0);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b011);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
void sh(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
|
||||
if (do_compress_zcb(Rd_Rs2, Rs1) &&
|
||||
(uimm == 0 || uimm == 2)) {
|
||||
c_sh(Rd_Rs2, Rs1, uimm);
|
||||
} else {
|
||||
_sh(Rd_Rs2, Rs1, uimm);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CS
|
||||
void c_zext_b(Register Rs1) {
|
||||
assert_cond(do_compress_zcb(Rs1));
|
||||
c_u_if<0b000>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zbb
|
||||
void sext_b(Register Rd_Rs2, Register Rs1) {
|
||||
assert_cond(UseZbb);
|
||||
if (do_compress_zcb_zbb(Rd_Rs2, Rs1) && (Rd_Rs2 == Rs1)) {
|
||||
c_sext_b(Rd_Rs2);
|
||||
} else {
|
||||
_sext_b(Rd_Rs2, Rs1);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb, Zbb
|
||||
// Format CS
|
||||
void c_sext_b(Register Rs1) {
|
||||
c_u_if<0b001>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zbb
|
||||
void zext_h(Register Rd_Rs2, Register Rs1) {
|
||||
assert_cond(UseZbb);
|
||||
if (do_compress_zcb_zbb(Rd_Rs2, Rs1) && (Rd_Rs2 == Rs1)) {
|
||||
c_zext_h(Rd_Rs2);
|
||||
} else {
|
||||
_zext_h(Rd_Rs2, Rs1);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb, Zbb
|
||||
// Format CS
|
||||
void c_zext_h(Register Rs1) {
|
||||
c_u_if<0b010>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zbb
|
||||
void sext_h(Register Rd_Rs2, Register Rs1) {
|
||||
assert_cond(UseZbb);
|
||||
if (do_compress_zcb_zbb(Rd_Rs2, Rs1) && (Rd_Rs2 == Rs1)) {
|
||||
c_sext_h(Rd_Rs2);
|
||||
} else {
|
||||
_sext_h(Rd_Rs2, Rs1);
|
||||
}
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb, Zbb
|
||||
// Format CS
|
||||
void c_sext_h(Register Rs1) {
|
||||
c_u_if<0b011>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb, Zba
|
||||
// Format CS
|
||||
void c_zext_w(Register Rs1) {
|
||||
c_u_if<0b100>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb
|
||||
// Format CS
|
||||
void c_not(Register Rs1) {
|
||||
c_u_if<0b101>(Rs1);
|
||||
}
|
||||
|
||||
// Prerequisites: Zcb (M or Zmmul)
|
||||
// Format CA, c.mul
|
||||
void c_mul(Register Rd_Rs1, Register Rs2) {
|
||||
uint16_t insn = 0;
|
||||
c_patch((address)&insn, 1, 0, 0b01);
|
||||
c_patch_compressed_reg((address)&insn, 2, Rs2);
|
||||
c_patch((address)&insn, 6, 5, 0b10);
|
||||
c_patch_compressed_reg((address)&insn, 7, Rd_Rs1);
|
||||
c_patch((address)&insn, 12, 10, 0b111);
|
||||
c_patch((address)&insn, 15, 13, 0b100);
|
||||
emit_int16(insn);
|
||||
}
|
||||
|
||||
void mul(Register Rd, Register Rs1, Register Rs2) {
|
||||
if (Rd != Rs1 && Rd != Rs2) {
|
||||
// Three registers needed without a mv, emit uncompressed
|
||||
_mul(Rd, Rs1, Rs2);
|
||||
return;
|
||||
}
|
||||
|
||||
// Rd is either Rs1 or Rs2
|
||||
if (!do_compress_zcb(Rs2, Rs1)) {
|
||||
_mul(Rd, Rs1, Rs2);
|
||||
} else {
|
||||
if (Rd == Rs2) {
|
||||
Rs2 = Rs1;
|
||||
} else {
|
||||
assert(Rd == Rs1, "must be");
|
||||
}
|
||||
c_mul(Rd, Rs2);
|
||||
}
|
||||
}
|
||||
|
||||
// Stack overflow checking
|
||||
virtual void bang_stack_with_offset(int offset) { Unimplemented(); }
|
||||
|
||||
@@ -2940,6 +3255,17 @@ public:
|
||||
return uabs(target - branch) < branch_range;
|
||||
}
|
||||
|
||||
// Decode the given instruction, checking if it's a 16-bit compressed
|
||||
// instruction and return the address of the next instruction.
|
||||
static address locate_next_instruction(address inst) {
|
||||
// Instruction wider than 16 bits has the two least-significant bits set.
|
||||
if ((0x3 & *inst) == 0x3) {
|
||||
return inst + instruction_size;
|
||||
} else {
|
||||
return inst + compressed_instruction_size;
|
||||
}
|
||||
}
|
||||
|
||||
Assembler(CodeBuffer* code) : AbstractAssembler(code), _in_compressible_region(true) {}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@@ -121,10 +121,10 @@ void C2_MacroAssembler::fast_lock(Register objectReg, Register boxReg,
|
||||
|
||||
// Handle existing monitor.
|
||||
bind(object_has_monitor);
|
||||
// The object's monitor m is unlocked iff m->owner == NULL,
|
||||
// The object's monitor m is unlocked iff m->owner == nullptr,
|
||||
// otherwise m->owner may contain a thread or a stack address.
|
||||
//
|
||||
// Try to CAS m->owner from NULL to current thread.
|
||||
// Try to CAS m->owner from null to current thread.
|
||||
add(tmp, disp_hdr, (in_bytes(ObjectMonitor::owner_offset()) - markWord::monitor_value));
|
||||
cmpxchg(/*memory address*/tmp, /*expected value*/zr, /*new value*/xthread, Assembler::int64, Assembler::aq,
|
||||
Assembler::rl, /*result*/flag); // cas succeeds if flag == zr(expected)
|
||||
@@ -1459,6 +1459,112 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2,
|
||||
BLOCK_COMMENT("} string_equals");
|
||||
}
|
||||
|
||||
// jdk.internal.util.ArraysSupport.vectorizedHashCode
|
||||
void C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register result,
|
||||
Register tmp1, Register tmp2, Register tmp3,
|
||||
Register tmp4, Register tmp5, Register tmp6,
|
||||
BasicType eltype)
|
||||
{
|
||||
assert_different_registers(ary, cnt, result, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, t0, t1);
|
||||
|
||||
const int elsize = arrays_hashcode_elsize(eltype);
|
||||
const int chunks_end_shift = exact_log2(elsize);
|
||||
|
||||
switch (eltype) {
|
||||
case T_BOOLEAN: BLOCK_COMMENT("arrays_hashcode(unsigned byte) {"); break;
|
||||
case T_CHAR: BLOCK_COMMENT("arrays_hashcode(char) {"); break;
|
||||
case T_BYTE: BLOCK_COMMENT("arrays_hashcode(byte) {"); break;
|
||||
case T_SHORT: BLOCK_COMMENT("arrays_hashcode(short) {"); break;
|
||||
case T_INT: BLOCK_COMMENT("arrays_hashcode(int) {"); break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
const int stride = 4;
|
||||
const Register pow31_4 = tmp1;
|
||||
const Register pow31_3 = tmp2;
|
||||
const Register pow31_2 = tmp3;
|
||||
const Register chunks = tmp4;
|
||||
const Register chunks_end = chunks;
|
||||
|
||||
Label DONE, TAIL, TAIL_LOOP, WIDE_LOOP;
|
||||
|
||||
// result has a value initially
|
||||
|
||||
beqz(cnt, DONE);
|
||||
|
||||
andi(chunks, cnt, ~(stride-1));
|
||||
beqz(chunks, TAIL);
|
||||
|
||||
mv(pow31_4, 923521); // [31^^4]
|
||||
mv(pow31_3, 29791); // [31^^3]
|
||||
mv(pow31_2, 961); // [31^^2]
|
||||
|
||||
slli(chunks_end, chunks, chunks_end_shift);
|
||||
add(chunks_end, ary, chunks_end);
|
||||
andi(cnt, cnt, stride-1); // don't forget about tail!
|
||||
|
||||
bind(WIDE_LOOP);
|
||||
mulw(result, result, pow31_4); // 31^^4 * h
|
||||
arrays_hashcode_elload(t0, Address(ary, 0 * elsize), eltype);
|
||||
arrays_hashcode_elload(t1, Address(ary, 1 * elsize), eltype);
|
||||
arrays_hashcode_elload(tmp5, Address(ary, 2 * elsize), eltype);
|
||||
arrays_hashcode_elload(tmp6, Address(ary, 3 * elsize), eltype);
|
||||
mulw(t0, t0, pow31_3); // 31^^3 * ary[i+0]
|
||||
addw(result, result, t0);
|
||||
mulw(t1, t1, pow31_2); // 31^^2 * ary[i+1]
|
||||
addw(result, result, t1);
|
||||
slli(t0, tmp5, 5); // optimize 31^^1 * ary[i+2]
|
||||
subw(tmp5, t0, tmp5); // with ary[i+2]<<5 - ary[i+2]
|
||||
addw(result, result, tmp5);
|
||||
addw(result, result, tmp6); // 31^^4 * h + 31^^3 * ary[i+0] + 31^^2 * ary[i+1]
|
||||
// + 31^^1 * ary[i+2] + 31^^0 * ary[i+3]
|
||||
addi(ary, ary, elsize * stride);
|
||||
bne(ary, chunks_end, WIDE_LOOP);
|
||||
beqz(cnt, DONE);
|
||||
|
||||
bind(TAIL);
|
||||
slli(chunks_end, cnt, chunks_end_shift);
|
||||
add(chunks_end, ary, chunks_end);
|
||||
|
||||
bind(TAIL_LOOP);
|
||||
arrays_hashcode_elload(t0, Address(ary), eltype);
|
||||
slli(t1, result, 5); // optimize 31 * result
|
||||
subw(result, t1, result); // with result<<5 - result
|
||||
addw(result, result, t0);
|
||||
addi(ary, ary, elsize);
|
||||
bne(ary, chunks_end, TAIL_LOOP);
|
||||
|
||||
bind(DONE);
|
||||
BLOCK_COMMENT("} // arrays_hashcode");
|
||||
}
|
||||
|
||||
int C2_MacroAssembler::arrays_hashcode_elsize(BasicType eltype) {
|
||||
switch (eltype) {
|
||||
case T_BOOLEAN: return sizeof(jboolean);
|
||||
case T_BYTE: return sizeof(jbyte);
|
||||
case T_SHORT: return sizeof(jshort);
|
||||
case T_CHAR: return sizeof(jchar);
|
||||
case T_INT: return sizeof(jint);
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::arrays_hashcode_elload(Register dst, Address src, BasicType eltype) {
|
||||
switch (eltype) {
|
||||
// T_BOOLEAN used as surrogate for unsigned byte
|
||||
case T_BOOLEAN: lbu(dst, src); break;
|
||||
case T_BYTE: lb(dst, src); break;
|
||||
case T_SHORT: lh(dst, src); break;
|
||||
case T_CHAR: lhu(dst, src); break;
|
||||
case T_INT: lw(dst, src); break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (Assembler::*conditional_branch_insn)(Register op1, Register op2, Label& label, bool is_far);
|
||||
typedef void (MacroAssembler::*float_conditional_branch_insn)(FloatRegister op1, FloatRegister op2, Label& label,
|
||||
bool is_far, bool is_unordered);
|
||||
@@ -1677,6 +1783,95 @@ void C2_MacroAssembler::signum_fp(FloatRegister dst, FloatRegister one, bool is_
|
||||
bind(done);
|
||||
}
|
||||
|
||||
static void float16_to_float_slow_path(C2_MacroAssembler& masm, C2GeneralStub<FloatRegister, Register, Register>& stub) {
|
||||
#define __ masm.
|
||||
FloatRegister dst = stub.data<0>();
|
||||
Register src = stub.data<1>();
|
||||
Register tmp = stub.data<2>();
|
||||
__ bind(stub.entry());
|
||||
|
||||
// following instructions mainly focus on NaN, as riscv does not handle
|
||||
// NaN well with fcvt, but the code also works for Inf at the same time.
|
||||
|
||||
// construct a NaN in 32 bits from the NaN in 16 bits,
|
||||
// we need the payloads of non-canonical NaNs to be preserved.
|
||||
__ mv(tmp, 0x7f800000);
|
||||
// sign-bit was already set via sign-extension if necessary.
|
||||
__ slli(t0, src, 13);
|
||||
__ orr(tmp, t0, tmp);
|
||||
__ fmv_w_x(dst, tmp);
|
||||
|
||||
__ j(stub.continuation());
|
||||
#undef __
|
||||
}
|
||||
|
||||
// j.l.Float.float16ToFloat
|
||||
void C2_MacroAssembler::float16_to_float(FloatRegister dst, Register src, Register tmp) {
|
||||
auto stub = C2CodeStub::make<FloatRegister, Register, Register>(dst, src, tmp, 20, float16_to_float_slow_path);
|
||||
|
||||
// in riscv, NaN needs a special process as fcvt does not work in that case.
|
||||
// in riscv, Inf does not need a special process as fcvt can handle it correctly.
|
||||
// but we consider to get the slow path to process NaN and Inf at the same time,
|
||||
// as both of them are rare cases, and if we try to get the slow path to handle
|
||||
// only NaN case it would sacrifise the performance for normal cases,
|
||||
// i.e. non-NaN and non-Inf cases.
|
||||
|
||||
// check whether it's a NaN or +/- Inf.
|
||||
mv(t0, 0x7c00);
|
||||
andr(tmp, src, t0);
|
||||
// jump to stub processing NaN and Inf cases.
|
||||
beq(t0, tmp, stub->entry());
|
||||
|
||||
// non-NaN or non-Inf cases, just use built-in instructions.
|
||||
fmv_h_x(dst, src);
|
||||
fcvt_s_h(dst, dst);
|
||||
|
||||
bind(stub->continuation());
|
||||
}
|
||||
|
||||
static void float_to_float16_slow_path(C2_MacroAssembler& masm, C2GeneralStub<Register, FloatRegister, Register>& stub) {
|
||||
#define __ masm.
|
||||
Register dst = stub.data<0>();
|
||||
FloatRegister src = stub.data<1>();
|
||||
Register tmp = stub.data<2>();
|
||||
__ bind(stub.entry());
|
||||
|
||||
__ fmv_x_w(dst, src);
|
||||
|
||||
// preserve the payloads of non-canonical NaNs.
|
||||
__ srai(dst, dst, 13);
|
||||
// preserve the sign bit.
|
||||
__ srai(tmp, dst, 13);
|
||||
__ slli(tmp, tmp, 10);
|
||||
__ mv(t0, 0x3ff);
|
||||
__ orr(tmp, tmp, t0);
|
||||
|
||||
// get the result by merging sign bit and payloads of preserved non-canonical NaNs.
|
||||
__ andr(dst, dst, tmp);
|
||||
|
||||
__ j(stub.continuation());
|
||||
#undef __
|
||||
}
|
||||
|
||||
// j.l.Float.floatToFloat16
|
||||
void C2_MacroAssembler::float_to_float16(Register dst, FloatRegister src, FloatRegister ftmp, Register xtmp) {
|
||||
auto stub = C2CodeStub::make<Register, FloatRegister, Register>(dst, src, xtmp, 130, float_to_float16_slow_path);
|
||||
|
||||
// in riscv, NaN needs a special process as fcvt does not work in that case.
|
||||
|
||||
// check whether it's a NaN.
|
||||
// replace fclass with feq as performance optimization.
|
||||
feq_s(t0, src, src);
|
||||
// jump to stub processing NaN cases.
|
||||
beqz(t0, stub->entry());
|
||||
|
||||
// non-NaN cases, just use built-in instructions.
|
||||
fcvt_h_s(ftmp, src);
|
||||
fmv_x_h(dst, ftmp);
|
||||
|
||||
bind(stub->continuation());
|
||||
}
|
||||
|
||||
void C2_MacroAssembler::signum_fp_v(VectorRegister dst, VectorRegister one, BasicType bt, int vlen) {
|
||||
vsetvli_helper(bt, vlen);
|
||||
|
||||
|
||||
@@ -82,6 +82,15 @@
|
||||
Register result, Register cnt1,
|
||||
int elem_size);
|
||||
|
||||
void arrays_hashcode(Register ary, Register cnt, Register result,
|
||||
Register tmp1, Register tmp2,
|
||||
Register tmp3, Register tmp4,
|
||||
Register tmp5, Register tmp6,
|
||||
BasicType eltype);
|
||||
// helper function for arrays_hashcode
|
||||
int arrays_hashcode_elsize(BasicType eltype);
|
||||
void arrays_hashcode_elload(Register dst, Address src, BasicType eltype);
|
||||
|
||||
void string_equals(Register r1, Register r2,
|
||||
Register result, Register cnt1,
|
||||
int elem_size);
|
||||
@@ -163,8 +172,12 @@
|
||||
|
||||
void signum_fp(FloatRegister dst, FloatRegister one, bool is_double);
|
||||
|
||||
void float16_to_float(FloatRegister dst, Register src, Register tmp);
|
||||
void float_to_float16(Register dst, FloatRegister src, FloatRegister ftmp, Register xtmp);
|
||||
|
||||
void signum_fp_v(VectorRegister dst, VectorRegister one, BasicType bt, int vlen);
|
||||
|
||||
|
||||
// intrinsic methods implemented by rvv instructions
|
||||
|
||||
// compress bits, i.e. j.l.Integer/Long::compress.
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "code/compiledIC.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
@@ -88,9 +89,9 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
address stub = find_stub();
|
||||
guarantee(stub != nullptr, "stub not found");
|
||||
|
||||
if (TraceICs) {
|
||||
{
|
||||
ResourceMark rm;
|
||||
tty->print_cr("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
log_trace(inlinecache)("CompiledDirectStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
|
||||
p2i(instruction_address()),
|
||||
callee->name_and_sig_as_C_string());
|
||||
}
|
||||
|
||||
@@ -189,8 +189,6 @@
|
||||
static void verify_deopt_original_pc(CompiledMethod* nm, intptr_t* unextended_sp);
|
||||
#endif
|
||||
|
||||
const ImmutableOopMap* get_oop_map() const;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@@ -186,7 +186,7 @@ inline bool frame::equal(frame other) const {
|
||||
unextended_sp() == other.unextended_sp() &&
|
||||
fp() == other.fp() &&
|
||||
pc() == other.pc();
|
||||
assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
|
||||
assert(!ret || (cb() == other.cb() && _deopt_state == other._deopt_state), "inconsistent construction");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -345,20 +345,6 @@ inline int frame::sender_sp_ret_address_offset() {
|
||||
return frame::sender_sp_offset - frame::return_addr_offset;
|
||||
}
|
||||
|
||||
inline const ImmutableOopMap* frame::get_oop_map() const {
|
||||
if (_cb == nullptr) return nullptr;
|
||||
if (_cb->oop_maps() != nullptr) {
|
||||
NativePostCallNop* nop = nativePostCallNop_at(_pc);
|
||||
if (nop != nullptr && nop->displacement() != 0) {
|
||||
int slot = ((nop->displacement() >> 24) & 0xff);
|
||||
return _cb->oop_map_for_slot(slot, _pc);
|
||||
}
|
||||
const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
|
||||
return oop_map;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::sender
|
||||
frame frame::sender(RegisterMap* map) const {
|
||||
|
||||
@@ -52,11 +52,11 @@ static void x_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node
|
||||
%}
|
||||
|
||||
// Load Pointer
|
||||
instruct xLoadP(iRegPNoSp dst, memory mem)
|
||||
instruct xLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(UseZGC && !ZGenerational && (n->as_Load()->barrier_data() != 0));
|
||||
effect(TEMP dst);
|
||||
effect(TEMP dst, TEMP tmp);
|
||||
|
||||
ins_cost(4 * DEFAULT_COST);
|
||||
|
||||
@@ -65,17 +65,17 @@ instruct xLoadP(iRegPNoSp dst, memory mem)
|
||||
ins_encode %{
|
||||
const Address ref_addr (as_Register($mem$$base), $mem$$disp);
|
||||
__ ld($dst$$Register, ref_addr);
|
||||
x_load_barrier(_masm, this, ref_addr, $dst$$Register, t0 /* tmp */, barrier_data());
|
||||
x_load_barrier(_masm, this, ref_addr, $dst$$Register, $tmp$$Register /* tmp */, barrier_data());
|
||||
%}
|
||||
|
||||
ins_pipe(iload_reg_mem);
|
||||
%}
|
||||
|
||||
instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong);
|
||||
effect(KILL cr, TEMP_DEF res);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -86,17 +86,15 @@ instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
|
||||
Label failed;
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register,
|
||||
true /* result_as_bool */);
|
||||
__ beqz($res$$Register, failed);
|
||||
__ mv(t0, $oldval$$Register);
|
||||
__ bind(failed);
|
||||
Assembler::relaxed /* acquire */, Assembler::rl /* release */, $tmp$$Register);
|
||||
__ sub(t0, $tmp$$Register, $oldval$$Register);
|
||||
__ seqz($res$$Register, t0);
|
||||
if (barrier_data() != XLoadBarrierElided) {
|
||||
Label good;
|
||||
__ ld(t1, Address(xthread, XThreadLocalData::address_bad_mask_offset()), t1 /* tmp */);
|
||||
__ andr(t1, t1, t0);
|
||||
__ beqz(t1, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), t0 /* ref */, t1 /* tmp */);
|
||||
__ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(t0, t0, $tmp$$Register);
|
||||
__ beqz(t0, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $tmp$$Register /* ref */, $res$$Register /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register,
|
||||
true /* result_as_bool */);
|
||||
@@ -107,11 +105,11 @@ instruct xCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() == XLoadBarrierStrong));
|
||||
effect(KILL cr, TEMP_DEF res);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -122,17 +120,15 @@ instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
|
||||
Label failed;
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register,
|
||||
true /* result_as_bool */);
|
||||
__ beqz($res$$Register, failed);
|
||||
__ mv(t0, $oldval$$Register);
|
||||
__ bind(failed);
|
||||
Assembler::aq /* acquire */, Assembler::rl /* release */, $tmp$$Register);
|
||||
__ sub(t0, $tmp$$Register, $oldval$$Register);
|
||||
__ seqz($res$$Register, t0);
|
||||
if (barrier_data() != XLoadBarrierElided) {
|
||||
Label good;
|
||||
__ ld(t1, Address(xthread, XThreadLocalData::address_bad_mask_offset()), t1 /* tmp */);
|
||||
__ andr(t1, t1, t0);
|
||||
__ beqz(t1, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), t0 /* ref */, t1 /* tmp */);
|
||||
__ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(t0, t0, $tmp$$Register);
|
||||
__ beqz(t0, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $tmp$$Register /* ref */, $res$$Register /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register,
|
||||
true /* result_as_bool */);
|
||||
@@ -143,10 +139,10 @@ instruct xCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{
|
||||
instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong);
|
||||
effect(TEMP_DEF res);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -161,7 +157,7 @@ instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
__ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(t0, t0, $res$$Register);
|
||||
__ beqz(t0, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, t0 /* tmp */);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, $tmp$$Register /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register);
|
||||
__ bind(good);
|
||||
@@ -171,10 +167,10 @@ instruct xCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval) %{
|
||||
instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() == XLoadBarrierStrong);
|
||||
effect(TEMP_DEF res);
|
||||
effect(TEMP_DEF res, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -189,7 +185,7 @@ instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
__ ld(t0, Address(xthread, XThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(t0, t0, $res$$Register);
|
||||
__ beqz(t0, good);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, t0 /* tmp */);
|
||||
x_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, $tmp$$Register /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::int64,
|
||||
Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register);
|
||||
__ bind(good);
|
||||
@@ -199,10 +195,10 @@ instruct xCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && !ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -210,16 +206,16 @@ instruct xGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
|
||||
ins_encode %{
|
||||
__ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
|
||||
x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data());
|
||||
x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, $tmp$$Register /* tmp */, barrier_data());
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && !ZGenerational && needs_acquiring_load_reserved(n) && (n->as_LoadStore()->barrier_data() != 0));
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
|
||||
@@ -227,7 +223,7 @@ instruct xGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr)
|
||||
|
||||
ins_encode %{
|
||||
__ atomic_xchgal($prev$$Register, $newv$$Register, as_Register($mem$$base));
|
||||
x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, t0 /* tmp */, barrier_data());
|
||||
x_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, $tmp$$Register /* tmp */, barrier_data());
|
||||
%}
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
@@ -79,7 +79,7 @@ static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address
|
||||
|
||||
static void z_store_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register rnew_zaddress, Register rnew_zpointer, Register tmp, bool is_atomic) {
|
||||
if (node->barrier_data() == ZBarrierElided) {
|
||||
z_color(_masm, node, rnew_zpointer, rnew_zaddress, t0);
|
||||
z_color(_masm, node, rnew_zpointer, rnew_zaddress, tmp);
|
||||
} else {
|
||||
bool is_native = (node->barrier_data() & ZBarrierNative) != 0;
|
||||
ZStoreBarrierStubC2* const stub = ZStoreBarrierStubC2::create(node, ref_addr, rnew_zaddress, rnew_zpointer, is_native, is_atomic);
|
||||
@@ -90,11 +90,11 @@ static void z_store_barrier(MacroAssembler& _masm, const MachNode* node, Address
|
||||
%}
|
||||
|
||||
// Load Pointer
|
||||
instruct zLoadP(iRegPNoSp dst, memory mem)
|
||||
instruct zLoadP(iRegPNoSp dst, memory mem, iRegPNoSp tmp)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(UseZGC && ZGenerational && n->as_Load()->barrier_data() != 0);
|
||||
effect(TEMP dst);
|
||||
effect(TEMP dst, TEMP tmp);
|
||||
|
||||
ins_cost(4 * DEFAULT_COST);
|
||||
|
||||
@@ -103,34 +103,35 @@ instruct zLoadP(iRegPNoSp dst, memory mem)
|
||||
ins_encode %{
|
||||
const Address ref_addr(as_Register($mem$$base), $mem$$disp);
|
||||
__ ld($dst$$Register, ref_addr);
|
||||
z_load_barrier(_masm, this, ref_addr, $dst$$Register, t0);
|
||||
z_load_barrier(_masm, this, ref_addr, $dst$$Register, $tmp$$Register);
|
||||
%}
|
||||
|
||||
ins_pipe(iload_reg_mem);
|
||||
%}
|
||||
|
||||
// Store Pointer
|
||||
instruct zStoreP(memory mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
|
||||
instruct zStoreP(memory mem, iRegP src, iRegPNoSp tmp1, iRegPNoSp tmp2)
|
||||
%{
|
||||
predicate(UseZGC && ZGenerational && n->as_Store()->barrier_data() != 0);
|
||||
match(Set mem (StoreP mem src));
|
||||
effect(TEMP tmp, KILL cr);
|
||||
effect(TEMP tmp1, TEMP tmp2);
|
||||
|
||||
ins_cost(125); // XXX
|
||||
format %{ "sd $mem, $src\t# ptr" %}
|
||||
ins_encode %{
|
||||
const Address ref_addr(as_Register($mem$$base), $mem$$disp);
|
||||
z_store_barrier(_masm, this, ref_addr, $src$$Register, $tmp$$Register, t1, false /* is_atomic */);
|
||||
__ sd($tmp$$Register, ref_addr);
|
||||
z_store_barrier(_masm, this, ref_addr, $src$$Register, $tmp1$$Register, $tmp2$$Register, false /* is_atomic */);
|
||||
__ sd($tmp1$$Register, ref_addr);
|
||||
%}
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{
|
||||
instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -140,19 +141,20 @@ instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newva
|
||||
ins_encode %{
|
||||
guarantee($mem$$disp == 0, "impossible encoding");
|
||||
Address ref_addr($mem$$Register);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, $tmp1$$Register);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, $tmp1$$Register, true /* is_atomic */);
|
||||
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register, true /* result_as_bool */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{
|
||||
instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -162,18 +164,19 @@ instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP ne
|
||||
ins_encode %{
|
||||
guarantee($mem$$disp == 0, "impossible encoding");
|
||||
Address ref_addr($mem$$Register);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, $tmp1$$Register);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, $tmp1$$Register, true /* is_atomic */);
|
||||
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register, true /* result_as_bool */);
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{
|
||||
instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -182,8 +185,8 @@ instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
ins_encode %{
|
||||
guarantee($mem$$disp == 0, "impossible encoding");
|
||||
Address ref_addr($mem$$Register);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, $tmp1$$Register);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, $tmp1$$Register, true /* is_atomic */);
|
||||
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::relaxed /* acquire */, Assembler::rl /* release */, $res$$Register);
|
||||
z_uncolor(_masm, this, $res$$Register);
|
||||
%}
|
||||
@@ -191,10 +194,11 @@ instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP n
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, rFlagsReg cr) %{
|
||||
instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval,
|
||||
iRegPNoSp oldval_tmp, iRegPNoSp newval_tmp, iRegPNoSp tmp1) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, KILL cr, TEMP_DEF res);
|
||||
effect(TEMP oldval_tmp, TEMP newval_tmp, TEMP tmp1, TEMP_DEF res);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
@@ -203,8 +207,8 @@ instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
ins_encode %{
|
||||
guarantee($mem$$disp == 0, "impossible encoding");
|
||||
Address ref_addr($mem$$Register);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, t0);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, t1, true /* is_atomic */);
|
||||
z_color(_masm, this, $oldval_tmp$$Register, $oldval$$Register, $tmp1$$Register);
|
||||
z_store_barrier(_masm, this, ref_addr, $newval$$Register, $newval_tmp$$Register, $tmp1$$Register, true /* is_atomic */);
|
||||
__ cmpxchg($mem$$Register, $oldval_tmp$$Register, $newval_tmp$$Register, Assembler::int64, Assembler::aq /* acquire */, Assembler::rl /* release */, $res$$Register);
|
||||
z_uncolor(_masm, this, $res$$Register);
|
||||
%}
|
||||
@@ -212,17 +216,17 @@ instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iReg
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && ZGenerational && !needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
format %{ "atomic_xchg $prev, $newv, [$mem], #@zGetAndSetP" %}
|
||||
|
||||
ins_encode %{
|
||||
z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, t1, true /* is_atomic */);
|
||||
z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, $tmp$$Register, true /* is_atomic */);
|
||||
__ atomic_xchg($prev$$Register, $prev$$Register, $mem$$Register);
|
||||
z_uncolor(_masm, this, $prev$$Register);
|
||||
%}
|
||||
@@ -230,17 +234,17 @@ instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, iRegPNoSp tmp) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && ZGenerational && needs_acquiring_load_reserved(n) && n->as_LoadStore()->barrier_data() != 0);
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
effect(TEMP_DEF prev, TEMP tmp);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
format %{ "atomic_xchg_acq $prev, $newv, [$mem], #@zGetAndSetPAcq" %}
|
||||
|
||||
ins_encode %{
|
||||
z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, t1, true /* is_atomic */);
|
||||
z_store_barrier(_masm, this, Address($mem$$Register), $newv$$Register, $prev$$Register, $tmp$$Register, true /* is_atomic */);
|
||||
__ atomic_xchgal($prev$$Register, $prev$$Register, $mem$$Register);
|
||||
z_uncolor(_masm, this, $prev$$Register);
|
||||
%}
|
||||
|
||||
@@ -50,6 +50,10 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
|
||||
#define USE_POINTERS_TO_REGISTER_IMPL_ARRAY
|
||||
|
||||
// The expected size in bytes of a cache line.
|
||||
#define DEFAULT_CACHE_LINE_SIZE 64
|
||||
|
||||
// The default padding size for data structures to avoid false sharing.
|
||||
#define DEFAULT_PADDING_SIZE DEFAULT_CACHE_LINE_SIZE
|
||||
|
||||
#endif // CPU_RISCV_GLOBALDEFINITIONS_RISCV_HPP
|
||||
|
||||
@@ -105,6 +105,8 @@ define_pd_global(intx, InlineSmallCode, 1000);
|
||||
product(bool, UseZba, false, "Use Zba instructions") \
|
||||
product(bool, UseZbb, false, "Use Zbb instructions") \
|
||||
product(bool, UseZbs, false, "Use Zbs instructions") \
|
||||
product(bool, UseZfh, false, "Use Zfh instructions") \
|
||||
product(bool, UseZacas, false, EXPERIMENTAL, "Use Zacas instructions") \
|
||||
product(bool, UseZic64b, false, EXPERIMENTAL, "Use Zic64b instructions") \
|
||||
product(bool, UseZicbom, false, EXPERIMENTAL, "Use Zicbom instructions") \
|
||||
product(bool, UseZicbop, false, EXPERIMENTAL, "Use Zicbop instructions") \
|
||||
@@ -112,6 +114,8 @@ define_pd_global(intx, InlineSmallCode, 1000);
|
||||
product(bool, UseZtso, false, EXPERIMENTAL, "Assume Ztso memory model") \
|
||||
product(bool, UseZihintpause, false, EXPERIMENTAL, \
|
||||
"Use Zihintpause instructions") \
|
||||
product(bool, UseZvkn, false, EXPERIMENTAL, \
|
||||
"Use Zvkn group extension, Zvkned, Zvknhb, Zvkb, Zvkt") \
|
||||
product(bool, UseRVVForBigIntegerShiftIntrinsics, true, \
|
||||
"Use RVV instructions for left/right shift of BigInteger")
|
||||
|
||||
|
||||
@@ -777,7 +777,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg)
|
||||
assert(lock_offset == 0,
|
||||
"displached header must be first word in BasicObjectLock");
|
||||
|
||||
cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, t0, count, /*fallthrough*/nullptr);
|
||||
cmpxchg_obj_header(swap_reg, lock_reg, obj_reg, tmp, count, /*fallthrough*/nullptr);
|
||||
|
||||
// Test if the oopMark is an obvious stack pointer, i.e.,
|
||||
// 1) (mark & 7) == 0, and
|
||||
@@ -891,7 +891,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg)
|
||||
beqz(header_reg, count);
|
||||
|
||||
// Atomic swap back the old header
|
||||
cmpxchg_obj_header(swap_reg, header_reg, obj_reg, t0, count, /*fallthrough*/nullptr);
|
||||
cmpxchg_obj_header(swap_reg, header_reg, obj_reg, tmp_reg, count, /*fallthrough*/nullptr);
|
||||
}
|
||||
|
||||
// Call the runtime routine for slow case.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@@ -2725,27 +2725,36 @@ void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool acqui
|
||||
|
||||
void MacroAssembler::cmpxchgptr(Register oldv, Register newv, Register addr, Register tmp,
|
||||
Label &succeed, Label *fail) {
|
||||
assert_different_registers(addr, tmp);
|
||||
assert_different_registers(newv, tmp);
|
||||
assert_different_registers(oldv, tmp);
|
||||
assert_different_registers(addr, tmp, t0);
|
||||
assert_different_registers(newv, tmp, t0);
|
||||
assert_different_registers(oldv, tmp, t0);
|
||||
|
||||
// oldv holds comparison value
|
||||
// newv holds value to write in exchange
|
||||
// addr identifies memory word to compare against/update
|
||||
Label retry_load, nope;
|
||||
bind(retry_load);
|
||||
// Load reserved from the memory location
|
||||
load_reserved(tmp, addr, int64, Assembler::aqrl);
|
||||
// Fail and exit if it is not what we expect
|
||||
bne(tmp, oldv, nope);
|
||||
// If the store conditional succeeds, tmp will be zero
|
||||
store_conditional(tmp, newv, addr, int64, Assembler::rl);
|
||||
beqz(tmp, succeed);
|
||||
// Retry only when the store conditional failed
|
||||
j(retry_load);
|
||||
if (UseZacas) {
|
||||
mv(tmp, oldv);
|
||||
atomic_cas(tmp, newv, addr, Assembler::int64, Assembler::aq, Assembler::rl);
|
||||
beq(tmp, oldv, succeed);
|
||||
} else {
|
||||
Label retry_load, nope;
|
||||
bind(retry_load);
|
||||
// Load reserved from the memory location
|
||||
load_reserved(tmp, addr, int64, Assembler::aqrl);
|
||||
// Fail and exit if it is not what we expect
|
||||
bne(tmp, oldv, nope);
|
||||
// If the store conditional succeeds, tmp will be zero
|
||||
store_conditional(tmp, newv, addr, int64, Assembler::rl);
|
||||
beqz(tmp, succeed);
|
||||
// Retry only when the store conditional failed
|
||||
j(retry_load);
|
||||
|
||||
bind(nope);
|
||||
bind(nope);
|
||||
}
|
||||
|
||||
// neither amocas nor lr/sc have an implied barrier in the failing case
|
||||
membar(AnyAny);
|
||||
|
||||
mv(oldv, tmp);
|
||||
if (fail != nullptr) {
|
||||
j(*fail);
|
||||
@@ -2771,7 +2780,7 @@ void MacroAssembler::load_reserved(Register dst,
|
||||
break;
|
||||
case uint32:
|
||||
lr_w(dst, addr, acquire);
|
||||
zero_extend(t0, t0, 32);
|
||||
zero_extend(dst, dst, 32);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@@ -2819,7 +2828,7 @@ void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expecte
|
||||
}
|
||||
sll(mask, mask, shift);
|
||||
|
||||
xori(not_mask, mask, -1);
|
||||
notr(not_mask, mask);
|
||||
|
||||
sll(expected, expected, shift);
|
||||
andr(expected, expected, mask);
|
||||
@@ -2829,7 +2838,7 @@ void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expecte
|
||||
}
|
||||
|
||||
// cmpxchg_narrow_value will kill t0, t1, expected, new_val and tmps.
|
||||
// It's designed to implement compare and swap byte/boolean/char/short by lr.w/sc.w,
|
||||
// It's designed to implement compare and swap byte/boolean/char/short by lr.w/sc.w or amocas.w,
|
||||
// which are forced to work with 4-byte aligned address.
|
||||
void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected,
|
||||
Register new_val,
|
||||
@@ -2844,14 +2853,29 @@ void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected,
|
||||
Label retry, fail, done;
|
||||
|
||||
bind(retry);
|
||||
lr_w(old, aligned_addr, acquire);
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
sc_w(tmp, tmp, aligned_addr, release);
|
||||
bnez(tmp, retry);
|
||||
if (UseZacas) {
|
||||
lw(old, aligned_addr);
|
||||
|
||||
// if old & mask != expected
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
|
||||
atomic_cas(old, tmp, aligned_addr, operand_size::int32, acquire, release);
|
||||
bne(tmp, old, retry);
|
||||
} else {
|
||||
lr_w(old, aligned_addr, acquire);
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
sc_w(tmp, tmp, aligned_addr, release);
|
||||
bnez(tmp, retry);
|
||||
}
|
||||
|
||||
if (result_as_bool) {
|
||||
mv(result, 1);
|
||||
@@ -2891,14 +2915,28 @@ void MacroAssembler::weak_cmpxchg_narrow_value(Register addr, Register expected,
|
||||
|
||||
Label fail, done;
|
||||
|
||||
lr_w(old, aligned_addr, acquire);
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
if (UseZacas) {
|
||||
lw(old, aligned_addr);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
sc_w(tmp, tmp, aligned_addr, release);
|
||||
bnez(tmp, fail);
|
||||
// if old & mask != expected
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
|
||||
atomic_cas(tmp, new_val, addr, operand_size::int32, acquire, release);
|
||||
bne(tmp, old, fail);
|
||||
} else {
|
||||
lr_w(old, aligned_addr, acquire);
|
||||
andr(tmp, old, mask);
|
||||
bne(tmp, expected, fail);
|
||||
|
||||
andr(tmp, old, not_mask);
|
||||
orr(tmp, tmp, new_val);
|
||||
sc_w(tmp, tmp, aligned_addr, release);
|
||||
bnez(tmp, fail);
|
||||
}
|
||||
|
||||
// Success
|
||||
mv(result, 1);
|
||||
@@ -2921,6 +2959,19 @@ void MacroAssembler::cmpxchg(Register addr, Register expected,
|
||||
assert_different_registers(expected, t0);
|
||||
assert_different_registers(new_val, t0);
|
||||
|
||||
if (UseZacas) {
|
||||
if (result_as_bool) {
|
||||
mv(t0, expected);
|
||||
atomic_cas(t0, new_val, addr, size, acquire, release);
|
||||
xorr(t0, t0, expected);
|
||||
seqz(result, t0);
|
||||
} else {
|
||||
mv(result, expected);
|
||||
atomic_cas(result, new_val, addr, size, acquire, release);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Label retry_load, done, ne_done;
|
||||
bind(retry_load);
|
||||
load_reserved(t0, addr, size, acquire);
|
||||
@@ -2952,6 +3003,11 @@ void MacroAssembler::cmpxchg_weak(Register addr, Register expected,
|
||||
enum operand_size size,
|
||||
Assembler::Aqrl acquire, Assembler::Aqrl release,
|
||||
Register result) {
|
||||
if (UseZacas) {
|
||||
cmpxchg(addr, expected, new_val, size, acquire, release, result, true);
|
||||
return;
|
||||
}
|
||||
|
||||
assert_different_registers(addr, t0);
|
||||
assert_different_registers(expected, t0);
|
||||
assert_different_registers(new_val, t0);
|
||||
@@ -3018,6 +3074,89 @@ ATOMIC_XCHGU(xchgalwu, xchgalw)
|
||||
|
||||
#undef ATOMIC_XCHGU
|
||||
|
||||
#define ATOMIC_CAS(OP, AOP, ACQUIRE, RELEASE) \
|
||||
void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) { \
|
||||
assert(UseZacas, "invariant"); \
|
||||
prev = prev->is_valid() ? prev : zr; \
|
||||
AOP(prev, addr, newv, (Assembler::Aqrl)(ACQUIRE | RELEASE)); \
|
||||
return; \
|
||||
}
|
||||
|
||||
ATOMIC_CAS(cas, amocas_d, Assembler::relaxed, Assembler::relaxed)
|
||||
ATOMIC_CAS(casw, amocas_w, Assembler::relaxed, Assembler::relaxed)
|
||||
ATOMIC_CAS(casl, amocas_d, Assembler::relaxed, Assembler::rl)
|
||||
ATOMIC_CAS(caslw, amocas_w, Assembler::relaxed, Assembler::rl)
|
||||
ATOMIC_CAS(casal, amocas_d, Assembler::aq, Assembler::rl)
|
||||
ATOMIC_CAS(casalw, amocas_w, Assembler::aq, Assembler::rl)
|
||||
|
||||
#undef ATOMIC_CAS
|
||||
|
||||
#define ATOMIC_CASU(OP1, OP2) \
|
||||
void MacroAssembler::atomic_##OP1(Register prev, Register newv, Register addr) { \
|
||||
atomic_##OP2(prev, newv, addr); \
|
||||
zero_extend(prev, prev, 32); \
|
||||
return; \
|
||||
}
|
||||
|
||||
ATOMIC_CASU(caswu, casw)
|
||||
ATOMIC_CASU(caslwu, caslw)
|
||||
ATOMIC_CASU(casalwu, casalw)
|
||||
|
||||
#undef ATOMIC_CASU
|
||||
|
||||
void MacroAssembler::atomic_cas(
|
||||
Register prev, Register newv, Register addr, enum operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release) {
|
||||
switch (size) {
|
||||
case int64:
|
||||
switch ((Assembler::Aqrl)(acquire | release)) {
|
||||
case Assembler::relaxed:
|
||||
atomic_cas(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::rl:
|
||||
atomic_casl(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::aqrl:
|
||||
atomic_casal(prev, newv, addr);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
break;
|
||||
case int32:
|
||||
switch ((Assembler::Aqrl)(acquire | release)) {
|
||||
case Assembler::relaxed:
|
||||
atomic_casw(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::rl:
|
||||
atomic_caslw(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::aqrl:
|
||||
atomic_casalw(prev, newv, addr);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
break;
|
||||
case uint32:
|
||||
switch ((Assembler::Aqrl)(acquire | release)) {
|
||||
case Assembler::relaxed:
|
||||
atomic_caswu(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::rl:
|
||||
atomic_caslwu(prev, newv, addr);
|
||||
break;
|
||||
case Assembler::aqrl:
|
||||
atomic_casalwu(prev, newv, addr);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::far_jump(const Address &entry, Register tmp) {
|
||||
assert(ReservedCodeCacheSize < 4*G, "branch out of range");
|
||||
assert(CodeCache::find_blob(entry.target()) != nullptr,
|
||||
@@ -4342,6 +4481,57 @@ void MacroAssembler::zero_dcache_blocks(Register base, Register cnt, Register tm
|
||||
bge(cnt, tmp1, loop);
|
||||
}
|
||||
|
||||
// java.lang.Math.round(float a)
|
||||
// Returns the closest int to the argument, with ties rounding to positive infinity.
|
||||
void MacroAssembler::java_round_float(Register dst, FloatRegister src, FloatRegister ftmp) {
|
||||
// this instructions calling sequence provides performance improvement on all tested devices;
|
||||
// don't change it without re-verification
|
||||
Label done;
|
||||
mv(t0, jint_cast(0.5f));
|
||||
fmv_w_x(ftmp, t0);
|
||||
|
||||
// dst = 0 if NaN
|
||||
feq_s(t0, src, src); // replacing fclass with feq as performance optimization
|
||||
mv(dst, zr);
|
||||
beqz(t0, done);
|
||||
|
||||
// dst = (src + 0.5f) rounded down towards negative infinity
|
||||
// Adding 0.5f to some floats exceeds the precision limits for a float and rounding takes place.
|
||||
// RDN is required for fadd_s, RNE gives incorrect results:
|
||||
// --------------------------------------------------------------------
|
||||
// fadd.s rne (src + 0.5f): src = 8388609.000000 ftmp = 8388610.000000
|
||||
// fcvt.w.s rdn: ftmp = 8388610.000000 dst = 8388610
|
||||
// --------------------------------------------------------------------
|
||||
// fadd.s rdn (src + 0.5f): src = 8388609.000000 ftmp = 8388609.000000
|
||||
// fcvt.w.s rdn: ftmp = 8388609.000000 dst = 8388609
|
||||
// --------------------------------------------------------------------
|
||||
fadd_s(ftmp, src, ftmp, RoundingMode::rdn);
|
||||
fcvt_w_s(dst, ftmp, RoundingMode::rdn);
|
||||
|
||||
bind(done);
|
||||
}
|
||||
|
||||
// java.lang.Math.round(double a)
|
||||
// Returns the closest long to the argument, with ties rounding to positive infinity.
|
||||
void MacroAssembler::java_round_double(Register dst, FloatRegister src, FloatRegister ftmp) {
|
||||
// this instructions calling sequence provides performance improvement on all tested devices;
|
||||
// don't change it without re-verification
|
||||
Label done;
|
||||
mv(t0, julong_cast(0.5));
|
||||
fmv_d_x(ftmp, t0);
|
||||
|
||||
// dst = 0 if NaN
|
||||
feq_d(t0, src, src); // replacing fclass with feq as performance optimization
|
||||
mv(dst, zr);
|
||||
beqz(t0, done);
|
||||
|
||||
// dst = (src + 0.5) rounded down towards negative infinity
|
||||
fadd_d(ftmp, src, ftmp, RoundingMode::rdn); // RDN is required here otherwise some inputs produce incorrect results
|
||||
fcvt_l_d(dst, ftmp, RoundingMode::rdn);
|
||||
|
||||
bind(done);
|
||||
}
|
||||
|
||||
#define FCVT_SAFE(FLOATCVT, FLOATSIG) \
|
||||
void MacroAssembler::FLOATCVT##_safe(Register dst, FloatRegister src, Register tmp) { \
|
||||
Label done; \
|
||||
@@ -4488,41 +4678,54 @@ void MacroAssembler::shadd(Register Rd, Register Rs1, Register Rs2, Register tmp
|
||||
}
|
||||
|
||||
void MacroAssembler::zero_extend(Register dst, Register src, int bits) {
|
||||
if (UseZba && bits == 32) {
|
||||
zext_w(dst, src);
|
||||
return;
|
||||
}
|
||||
|
||||
if (UseZbb && bits == 16) {
|
||||
zext_h(dst, src);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bits == 8) {
|
||||
zext_b(dst, src);
|
||||
} else {
|
||||
slli(dst, src, XLEN - bits);
|
||||
srli(dst, dst, XLEN - bits);
|
||||
switch (bits) {
|
||||
case 32:
|
||||
if (UseZba) {
|
||||
zext_w(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (UseZbb) {
|
||||
zext_h(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (UseZbb) {
|
||||
zext_b(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
slli(dst, src, XLEN - bits);
|
||||
srli(dst, dst, XLEN - bits);
|
||||
}
|
||||
|
||||
void MacroAssembler::sign_extend(Register dst, Register src, int bits) {
|
||||
if (UseZbb) {
|
||||
if (bits == 8) {
|
||||
sext_b(dst, src);
|
||||
switch (bits) {
|
||||
case 32:
|
||||
sext_w(dst, src);
|
||||
return;
|
||||
} else if (bits == 16) {
|
||||
sext_h(dst, src);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (bits == 32) {
|
||||
sext_w(dst, src);
|
||||
} else {
|
||||
slli(dst, src, XLEN - bits);
|
||||
srai(dst, dst, XLEN - bits);
|
||||
case 16:
|
||||
if (UseZbb) {
|
||||
sext_h(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (UseZbb) {
|
||||
sext_b(dst, src);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
slli(dst, src, XLEN - bits);
|
||||
srai(dst, dst, XLEN - bits);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_x2i(Register dst, Register src1, Register src2,
|
||||
@@ -4701,9 +4904,9 @@ void MacroAssembler::object_move(OopMap* map,
|
||||
|
||||
// A float arg may have to do float reg int reg conversion
|
||||
void MacroAssembler::float_move(VMRegPair src, VMRegPair dst, Register tmp) {
|
||||
assert(src.first()->is_stack() && dst.first()->is_stack() ||
|
||||
src.first()->is_reg() && dst.first()->is_reg() ||
|
||||
src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error");
|
||||
assert((src.first()->is_stack() && dst.first()->is_stack()) ||
|
||||
(src.first()->is_reg() && dst.first()->is_reg()) ||
|
||||
(src.first()->is_stack() && dst.first()->is_reg()), "Unexpected error");
|
||||
if (src.first()->is_stack()) {
|
||||
if (dst.first()->is_stack()) {
|
||||
lwu(tmp, Address(fp, reg2offset_in(src.first())));
|
||||
@@ -4745,9 +4948,9 @@ void MacroAssembler::long_move(VMRegPair src, VMRegPair dst, Register tmp) {
|
||||
|
||||
// A double move
|
||||
void MacroAssembler::double_move(VMRegPair src, VMRegPair dst, Register tmp) {
|
||||
assert(src.first()->is_stack() && dst.first()->is_stack() ||
|
||||
src.first()->is_reg() && dst.first()->is_reg() ||
|
||||
src.first()->is_stack() && dst.first()->is_reg(), "Unexpected error");
|
||||
assert((src.first()->is_stack() && dst.first()->is_stack()) ||
|
||||
(src.first()->is_reg() && dst.first()->is_reg()) ||
|
||||
(src.first()->is_stack() && dst.first()->is_reg()), "Unexpected error");
|
||||
if (src.first()->is_stack()) {
|
||||
if (dst.first()->is_stack()) {
|
||||
ld(tmp, Address(fp, reg2offset_in(src.first())));
|
||||
|
||||
@@ -473,7 +473,11 @@ class MacroAssembler: public Assembler {
|
||||
}
|
||||
|
||||
inline void notr(Register Rd, Register Rs) {
|
||||
xori(Rd, Rs, -1);
|
||||
if (do_compress_zcb(Rd, Rs) && (Rd == Rs)) {
|
||||
c_not(Rd);
|
||||
} else {
|
||||
xori(Rd, Rs, -1);
|
||||
}
|
||||
}
|
||||
|
||||
inline void neg(Register Rd, Register Rs) {
|
||||
@@ -489,7 +493,11 @@ class MacroAssembler: public Assembler {
|
||||
}
|
||||
|
||||
inline void zext_b(Register Rd, Register Rs) {
|
||||
andi(Rd, Rs, 0xFF);
|
||||
if (do_compress_zcb(Rd, Rs) && (Rd == Rs)) {
|
||||
c_zext_b(Rd);
|
||||
} else {
|
||||
andi(Rd, Rs, 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
inline void seqz(Register Rd, Register Rs) {
|
||||
@@ -511,7 +519,12 @@ class MacroAssembler: public Assembler {
|
||||
// Bit-manipulation extension pseudo instructions
|
||||
// zero extend word
|
||||
inline void zext_w(Register Rd, Register Rs) {
|
||||
add_uw(Rd, Rs, zr);
|
||||
assert(UseZba, "must be");
|
||||
if (do_compress_zcb(Rd, Rs) && (Rd == Rs)) {
|
||||
c_zext_w(Rd);
|
||||
} else {
|
||||
add_uw(Rd, Rs, zr);
|
||||
}
|
||||
}
|
||||
|
||||
// Floating-point data-processing pseudo instructions
|
||||
@@ -1063,6 +1076,19 @@ public:
|
||||
void atomic_xchgwu(Register prev, Register newv, Register addr);
|
||||
void atomic_xchgalwu(Register prev, Register newv, Register addr);
|
||||
|
||||
void atomic_cas(Register prev, Register newv, Register addr);
|
||||
void atomic_casw(Register prev, Register newv, Register addr);
|
||||
void atomic_casl(Register prev, Register newv, Register addr);
|
||||
void atomic_caslw(Register prev, Register newv, Register addr);
|
||||
void atomic_casal(Register prev, Register newv, Register addr);
|
||||
void atomic_casalw(Register prev, Register newv, Register addr);
|
||||
void atomic_caswu(Register prev, Register newv, Register addr);
|
||||
void atomic_caslwu(Register prev, Register newv, Register addr);
|
||||
void atomic_casalwu(Register prev, Register newv, Register addr);
|
||||
|
||||
void atomic_cas(Register prev, Register newv, Register addr, enum operand_size size,
|
||||
Assembler::Aqrl acquire = Assembler::relaxed, Assembler::Aqrl release = Assembler::relaxed);
|
||||
|
||||
// Emit a far call/jump. Only invalidates the tmp register which
|
||||
// is used to keep the entry address for jalr.
|
||||
// The address must be inside the code cache.
|
||||
@@ -1252,6 +1278,9 @@ public:
|
||||
void fcvt_w_d_safe(Register dst, FloatRegister src, Register tmp = t0);
|
||||
void fcvt_l_d_safe(Register dst, FloatRegister src, Register tmp = t0);
|
||||
|
||||
void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
|
||||
void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
|
||||
|
||||
// vector load/store unit-stride instructions
|
||||
void vlex_v(VectorRegister vd, Register base, Assembler::SEW sew, VectorMask vm = unmasked) {
|
||||
switch (sew) {
|
||||
@@ -1345,6 +1374,16 @@ public:
|
||||
vmfle_vv(vd, vs1, vs2, vm);
|
||||
}
|
||||
|
||||
inline void vmsltu_vi(VectorRegister Vd, VectorRegister Vs2, uint32_t imm, VectorMask vm = unmasked) {
|
||||
guarantee(imm >= 1 && imm <= 16, "imm is invalid");
|
||||
vmsleu_vi(Vd, Vs2, imm-1, vm);
|
||||
}
|
||||
|
||||
inline void vmsgeu_vi(VectorRegister Vd, VectorRegister Vs2, uint32_t imm, VectorMask vm = unmasked) {
|
||||
guarantee(imm >= 1 && imm <= 16, "imm is invalid");
|
||||
vmsgtu_vi(Vd, Vs2, imm-1, vm);
|
||||
}
|
||||
|
||||
// Copy mask register
|
||||
inline void vmmv_m(VectorRegister vd, VectorRegister vs) {
|
||||
vmand_mm(vd, vs, vs);
|
||||
@@ -1360,6 +1399,10 @@ public:
|
||||
vmxnor_mm(vd, vd, vd);
|
||||
}
|
||||
|
||||
inline void vnot_v(VectorRegister Vd, VectorRegister Vs, VectorMask vm = unmasked) {
|
||||
vxor_vi(Vd, Vs, -1, vm);
|
||||
}
|
||||
|
||||
static const int zero_words_block_size;
|
||||
|
||||
void cast_primitive_type(BasicType type, Register Rt) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user