mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-10 19:39:39 +01:00
Compare commits
534 Commits
jdk-21+4
...
jbr-dev-lo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75a7ec29fe | ||
|
|
372b24e140 | ||
|
|
ec072da64b | ||
|
|
66bacd6534 | ||
|
|
5cbed8aca8 | ||
|
|
2cc4bd4b66 | ||
|
|
11b7883430 | ||
|
|
f71fdf9f69 | ||
|
|
06811192cf | ||
|
|
2ef6f228f2 | ||
|
|
1eeadc6f6c | ||
|
|
7ce53b02f9 | ||
|
|
4a3a5bde83 | ||
|
|
f80fbbc20f | ||
|
|
b3d6b00942 | ||
|
|
0053751c62 | ||
|
|
2718de16f8 | ||
|
|
876e5627a1 | ||
|
|
0ae8553922 | ||
|
|
a12e18dd40 | ||
|
|
5db1bfb301 | ||
|
|
beb14ead6e | ||
|
|
09f74b5e9d | ||
|
|
87ef8aad1c | ||
|
|
a0b44ca163 | ||
|
|
c371bfab90 | ||
|
|
a91686e2bc | ||
|
|
2801996066 | ||
|
|
fe33f0439b | ||
|
|
b4fa280202 | ||
|
|
669d95a590 | ||
|
|
63c841fdaf | ||
|
|
a574305e6a | ||
|
|
03d7998461 | ||
|
|
c5e1b2ff0a | ||
|
|
e5a74a160a | ||
|
|
68f2cf5c2d | ||
|
|
3552a6c02e | ||
|
|
fad937fddc | ||
|
|
a87e857218 | ||
|
|
a891822c98 | ||
|
|
92e4664981 | ||
|
|
aeebf64568 | ||
|
|
5044839ee7 | ||
|
|
9a918f2b70 | ||
|
|
6caabd7733 | ||
|
|
f014fb04e9 | ||
|
|
20e66ecca9 | ||
|
|
4b9518a9b1 | ||
|
|
7ed93ca4bb | ||
|
|
3f8b4df0ed | ||
|
|
f90caaa582 | ||
|
|
be90767767 | ||
|
|
61ed33ab9a | ||
|
|
f50e454702 | ||
|
|
79fc68bc41 | ||
|
|
c43e021cf3 | ||
|
|
630d0c7f71 | ||
|
|
397bee0aa9 | ||
|
|
e34c689645 | ||
|
|
a3c9614cdf | ||
|
|
baf1438e88 | ||
|
|
a2e4223f9a | ||
|
|
f322144a3f | ||
|
|
9b17fd7073 | ||
|
|
84345ec062 | ||
|
|
ec65de9f9b | ||
|
|
2ce2358900 | ||
|
|
5035fc8531 | ||
|
|
49e4c84346 | ||
|
|
970409b6c8 | ||
|
|
33db86b101 | ||
|
|
a83bb04324 | ||
|
|
63c478cfaf | ||
|
|
451cade255 | ||
|
|
153f3f8e7d | ||
|
|
f29236937e | ||
|
|
61f8a5ddd8 | ||
|
|
da7581b19f | ||
|
|
d60763f370 | ||
|
|
37e7d137aa | ||
|
|
69b1a00193 | ||
|
|
72a94c091b | ||
|
|
aa21879a81 | ||
|
|
96963c8334 | ||
|
|
ec6e377949 | ||
|
|
d7cf5e7210 | ||
|
|
e75a0903b8 | ||
|
|
516d278823 | ||
|
|
fa7af62829 | ||
|
|
4666032c34 | ||
|
|
8e5af2cd5e | ||
|
|
2a3b2d9e8d | ||
|
|
0271e312de | ||
|
|
0ad4c2b317 | ||
|
|
c0bff19699 | ||
|
|
7d981f4dcf | ||
|
|
176c42f588 | ||
|
|
f5ba8f993e | ||
|
|
dbe0956cf3 | ||
|
|
31308cae31 | ||
|
|
f1a411562c | ||
|
|
9721b52594 | ||
|
|
5d7448a4f7 | ||
|
|
dff7e4f132 | ||
|
|
4dc0660960 | ||
|
|
525526bacd | ||
|
|
705468c6bf | ||
|
|
a215841a7e | ||
|
|
0a89372971 | ||
|
|
0693457570 | ||
|
|
cba4cae26c | ||
|
|
e31c7c6008 | ||
|
|
bbf15ab6c7 | ||
|
|
40b207f8e9 | ||
|
|
c3e5f64680 | ||
|
|
7632564a6b | ||
|
|
65b0a4433d | ||
|
|
44acf8a404 | ||
|
|
9b125591a9 | ||
|
|
270db4a1f8 | ||
|
|
daedcf4442 | ||
|
|
9573024783 | ||
|
|
8c3a02d052 | ||
|
|
36f56421dc | ||
|
|
0bf634f261 | ||
|
|
f0264a9d7e | ||
|
|
aed56d1c18 | ||
|
|
f53004b255 | ||
|
|
bc6e308048 | ||
|
|
977ae6de89 | ||
|
|
422a358709 | ||
|
|
032d5bf79a | ||
|
|
56a81cf6ac | ||
|
|
e7765059af | ||
|
|
80506b8e95 | ||
|
|
906934029f | ||
|
|
2c2bf01ea8 | ||
|
|
86e8d3e6ea | ||
|
|
1efcfccae4 | ||
|
|
9450bfdf98 | ||
|
|
c15293b165 | ||
|
|
a4f844bb24 | ||
|
|
8134944ac9 | ||
|
|
83fb3eca5b | ||
|
|
8836b6869f | ||
|
|
afc6fe795a | ||
|
|
750afee977 | ||
|
|
114770fc98 | ||
|
|
78ab370e38 | ||
|
|
d0dbea9fce | ||
|
|
16a11e96c4 | ||
|
|
06fd404595 | ||
|
|
f0da0d88a8 | ||
|
|
462dad45df | ||
|
|
99b5363f4d | ||
|
|
2ab80f445f | ||
|
|
93ddc36faa | ||
|
|
5b5c1d12aa | ||
|
|
2748b0dc2b | ||
|
|
081d9fb51e | ||
|
|
b2fe81c0f1 | ||
|
|
90afe47a39 | ||
|
|
0cf2bdbc9a | ||
|
|
54b1567a64 | ||
|
|
101d86e839 | ||
|
|
478277093f | ||
|
|
148d17b85a | ||
|
|
282894f260 | ||
|
|
6669cfbfa5 | ||
|
|
942067f66c | ||
|
|
93665a6171 | ||
|
|
cab4f80eb3 | ||
|
|
afc0e8ca5f | ||
|
|
0e769efff5 | ||
|
|
a08e6c16f7 | ||
|
|
3e9a2f2093 | ||
|
|
8d2812b48f | ||
|
|
c532e21e4d | ||
|
|
4fd89e6c07 | ||
|
|
7f809c7fae | ||
|
|
7e934997d5 | ||
|
|
ef00c76e10 | ||
|
|
2ca5b4001b | ||
|
|
16fa579e27 | ||
|
|
90a9ba66f7 | ||
|
|
55f0544363 | ||
|
|
592753b689 | ||
|
|
0387403842 | ||
|
|
33226b73f0 | ||
|
|
3442cb53d5 | ||
|
|
cfd3336058 | ||
|
|
49ca83a0a2 | ||
|
|
febb300c15 | ||
|
|
2a3fb2150d | ||
|
|
44fd156b4c | ||
|
|
5a9d7cb430 | ||
|
|
cca50c173b | ||
|
|
f915217923 | ||
|
|
c675ad0f07 | ||
|
|
6b62ef8cee | ||
|
|
c22f9e2805 | ||
|
|
78c87eda95 | ||
|
|
9cc8699c44 | ||
|
|
7a849566ea | ||
|
|
5527cc7db0 | ||
|
|
ed883d989c | ||
|
|
2c059b8543 | ||
|
|
8824b819dd | ||
|
|
cc228c1e8d | ||
|
|
23976434be | ||
|
|
e9e2e7328b | ||
|
|
6557657a2b | ||
|
|
27c53dd910 | ||
|
|
704a018dbd | ||
|
|
0d58f8c31e | ||
|
|
f97295a09f | ||
|
|
58e8d6ab35 | ||
|
|
24a8fccb03 | ||
|
|
d634a73a6f | ||
|
|
32d6bcbe0c | ||
|
|
58cc00100a | ||
|
|
76fd488255 | ||
|
|
0b8e96ba22 | ||
|
|
d0305d7034 | ||
|
|
51aae97e50 | ||
|
|
9acb7b0ba6 | ||
|
|
5069cef490 | ||
|
|
63d3b6fb7d | ||
|
|
efe8989063 | ||
|
|
17e0c8f44a | ||
|
|
a0ac939065 | ||
|
|
183d19b26b | ||
|
|
20cc6f0bc6 | ||
|
|
4af1d89db7 | ||
|
|
00a3a7baf3 | ||
|
|
46787ccd0a | ||
|
|
28bde363ec | ||
|
|
afaf8e2f13 | ||
|
|
b749350eb2 | ||
|
|
d233a14998 | ||
|
|
aec7b6a274 | ||
|
|
2567bc3cf6 | ||
|
|
4deec768cc | ||
|
|
8bdbdf6959 | ||
|
|
4a41eb7569 | ||
|
|
46199484be | ||
|
|
bd64acd4d9 | ||
|
|
54d22758c8 | ||
|
|
a2f605798c | ||
|
|
c365904834 | ||
|
|
1478151e3a | ||
|
|
1ffd4ad5a6 | ||
|
|
e074fb8e37 | ||
|
|
8338b3c92d | ||
|
|
f2c7b8ec1e | ||
|
|
5174e7697a | ||
|
|
15f6cb7b6f | ||
|
|
ffbe0b940d | ||
|
|
646fd8035a | ||
|
|
4dc3d86cc5 | ||
|
|
a119411022 | ||
|
|
b60f3838e8 | ||
|
|
c60fd9c9cc | ||
|
|
e164873099 | ||
|
|
570ccbec37 | ||
|
|
e4ea48276d | ||
|
|
d757d42689 | ||
|
|
8c3ddd4796 | ||
|
|
e234dd4f23 | ||
|
|
841c396b19 | ||
|
|
a110811d7c | ||
|
|
8f488b2a09 | ||
|
|
ed2ba3f0ec | ||
|
|
392e31da35 | ||
|
|
882cbf919a | ||
|
|
0e5df40eb7 | ||
|
|
930a39d265 | ||
|
|
8f00b4883f | ||
|
|
e3a1fbfa39 | ||
|
|
a273b2da27 | ||
|
|
b5306bf14d | ||
|
|
7ec528083b | ||
|
|
45dfbcbe9c | ||
|
|
0a1b7394d2 | ||
|
|
17d6b8ac3f | ||
|
|
7902c4098c | ||
|
|
20b86e0802 | ||
|
|
60fb61bbd6 | ||
|
|
d24dd9b466 | ||
|
|
f4bf1aca13 | ||
|
|
e575dd660b | ||
|
|
ba7f3d28d7 | ||
|
|
b403c0eb42 | ||
|
|
d8864f5664 | ||
|
|
11131d1d2c | ||
|
|
755e1166d4 | ||
|
|
3310d5bd9c | ||
|
|
9b11b2d011 | ||
|
|
3aac611fea | ||
|
|
25be00f2a1 | ||
|
|
f6d42a57b7 | ||
|
|
24142e95ac | ||
|
|
0abb930754 | ||
|
|
4b97d09302 | ||
|
|
0ff69e545c | ||
|
|
6c2a8b14bc | ||
|
|
8cc720c0d7 | ||
|
|
726ea1ef85 | ||
|
|
9f277fe3b6 | ||
|
|
4a04f43121 | ||
|
|
ed3e8433dd | ||
|
|
87505cdc91 | ||
|
|
124012b088 | ||
|
|
99b9254c8c | ||
|
|
1a3272c1e6 | ||
|
|
5683a7c810 | ||
|
|
f60e163c32 | ||
|
|
62bb04d832 | ||
|
|
c94fc65a6b | ||
|
|
c0109c7cef | ||
|
|
1d2cb3a253 | ||
|
|
237b476373 | ||
|
|
287fec3894 | ||
|
|
9648d97dfb | ||
|
|
c1b4356914 | ||
|
|
731587b65e | ||
|
|
a8a2b104c6 | ||
|
|
57893ddf78 | ||
|
|
414fea4996 | ||
|
|
acd6ae722b | ||
|
|
88d19ce6e3 | ||
|
|
cf988944d6 | ||
|
|
6b607907ea | ||
|
|
a7c5a81975 | ||
|
|
e2d3a762d2 | ||
|
|
65823814a1 | ||
|
|
776a28f36a | ||
|
|
3c563a59e5 | ||
|
|
aedd4646cd | ||
|
|
5d4b73608e | ||
|
|
a9ebe6d032 | ||
|
|
d0dfc4ef12 | ||
|
|
5cea51055f | ||
|
|
215c6f2972 | ||
|
|
394915d2e5 | ||
|
|
dbf5601ade | ||
|
|
11d3bebd9e | ||
|
|
a1210e6366 | ||
|
|
e58c46d05a | ||
|
|
e2d6261b50 | ||
|
|
e5c2ffa04a | ||
|
|
77c2006288 | ||
|
|
061ae08096 | ||
|
|
a3af171586 | ||
|
|
5227b197c1 | ||
|
|
76eb62b675 | ||
|
|
0c8be52d97 | ||
|
|
63e8fa4ee2 | ||
|
|
2b2b999f87 | ||
|
|
8769933051 | ||
|
|
02d3b947c1 | ||
|
|
ea17159da7 | ||
|
|
45c893cab4 | ||
|
|
656e6e15a9 | ||
|
|
9951369679 | ||
|
|
bd03033ac4 | ||
|
|
b5d66d5afc | ||
|
|
41dce74c3c | ||
|
|
1c8832eda2 | ||
|
|
71fb5ec98b | ||
|
|
ae5666a595 | ||
|
|
18620b2c82 | ||
|
|
1a691039a8 | ||
|
|
957ebab247 | ||
|
|
1c47c70f29 | ||
|
|
57accc6015 | ||
|
|
244ae46506 | ||
|
|
5979ebd27c | ||
|
|
7b7608211d | ||
|
|
36c87c0bbe | ||
|
|
a944d5c13e | ||
|
|
dafa79274e | ||
|
|
e9ed291d44 | ||
|
|
7b49c42604 | ||
|
|
090e8f4daf | ||
|
|
cbbccd6ffe | ||
|
|
7e9541c575 | ||
|
|
74e0b73111 | ||
|
|
e66444d61d | ||
|
|
e91eca830e | ||
|
|
79d24d8dd7 | ||
|
|
814fd5a823 | ||
|
|
fcaaaf2b4e | ||
|
|
c03c87f193 | ||
|
|
2019103e48 | ||
|
|
9314b1f5d2 | ||
|
|
80f1114934 | ||
|
|
057e901125 | ||
|
|
1f3231943b | ||
|
|
dc03c5f8b7 | ||
|
|
8dcbaab9bf | ||
|
|
290f1b2baf | ||
|
|
2742a03800 | ||
|
|
42d95eb63e | ||
|
|
ccdefa5cde | ||
|
|
91c685708a | ||
|
|
64829047d4 | ||
|
|
30072c96bb | ||
|
|
c7e8def5bd | ||
|
|
622438b39e | ||
|
|
5baae32df2 | ||
|
|
9b214e8bf0 | ||
|
|
28da597e94 | ||
|
|
788450f724 | ||
|
|
39052c5721 | ||
|
|
36f4d16525 | ||
|
|
f53a6ababd | ||
|
|
51758fbb3d | ||
|
|
19862d22b8 | ||
|
|
f8bce66a98 | ||
|
|
977593a8ae | ||
|
|
af7ff48e46 | ||
|
|
34768a931e | ||
|
|
e642756a4c | ||
|
|
d78e3a3407 | ||
|
|
4a1954e8b1 | ||
|
|
19c436c986 | ||
|
|
dc871060c9 | ||
|
|
fa9d5a598f | ||
|
|
f2af81597a | ||
|
|
1234870ab5 | ||
|
|
fcbaceef90 | ||
|
|
b2de155964 | ||
|
|
b2f622d427 | ||
|
|
a216bfc84c | ||
|
|
73a1a07e34 | ||
|
|
b8aedb6946 | ||
|
|
5be3845d0b | ||
|
|
418fef826a | ||
|
|
7cbb59f710 | ||
|
|
0ef7ccfc21 | ||
|
|
ec5a92b514 | ||
|
|
add88af134 | ||
|
|
8ec3ea7968 | ||
|
|
4d047f4b71 | ||
|
|
85a5a3d8b1 | ||
|
|
f6b2d17e6d | ||
|
|
4e99a80d1e | ||
|
|
6379de8082 | ||
|
|
1d052a241f | ||
|
|
50d1ed0e1e | ||
|
|
dbf7331160 | ||
|
|
ccc056e8a9 | ||
|
|
f683600356 | ||
|
|
4132fa31ec | ||
|
|
652d5037d9 | ||
|
|
5f3e3a6f75 | ||
|
|
92b4375370 | ||
|
|
99b8c3164c | ||
|
|
34378ae089 | ||
|
|
88f241b49a | ||
|
|
3365c8ddd5 | ||
|
|
99e7ad356e | ||
|
|
309b880c8b | ||
|
|
323596f1bf | ||
|
|
463d44d022 | ||
|
|
7b6dc2454a | ||
|
|
278ac75261 | ||
|
|
aebc71869d | ||
|
|
e75718e907 | ||
|
|
56f1b8b97c | ||
|
|
7d17b7b417 | ||
|
|
aa68934d7a | ||
|
|
24ae1f42e3 | ||
|
|
1fc2d876b9 | ||
|
|
5673793ee0 | ||
|
|
b4e0477b6b | ||
|
|
d0c00167fe | ||
|
|
ef1b0d13db | ||
|
|
06d3dea9bd | ||
|
|
743717d23c | ||
|
|
453a26b305 | ||
|
|
e5f3ba9966 | ||
|
|
724bfdc8d4 | ||
|
|
2e69e6aa99 | ||
|
|
7d60620537 | ||
|
|
43215123f1 | ||
|
|
b58b1209ca | ||
|
|
cef8c581c1 | ||
|
|
dd9ec811a1 | ||
|
|
2f20939b88 | ||
|
|
5185cd3eb5 | ||
|
|
c7a5b9b85b | ||
|
|
4f20fcbd22 | ||
|
|
9594d294d1 | ||
|
|
ce880a2b94 | ||
|
|
6afedfa13c | ||
|
|
9358e73809 | ||
|
|
dfe1955c0c | ||
|
|
17e40dc336 | ||
|
|
15d6e4657e | ||
|
|
9eb742b44e | ||
|
|
170eda44b2 | ||
|
|
fcfc91b07a | ||
|
|
1afb287660 | ||
|
|
bfbf24daf7 | ||
|
|
aa123e53aa | ||
|
|
2c99a032f7 | ||
|
|
45fd1b40de | ||
|
|
230b24adb3 | ||
|
|
d5fb9599bc | ||
|
|
4c81f7662a | ||
|
|
e991e69902 | ||
|
|
a740675de9 | ||
|
|
b680b0a00d | ||
|
|
1bdc92bd97 | ||
|
|
6c2b822c22 | ||
|
|
47ebda49e9 | ||
|
|
5c70d4e2dd | ||
|
|
332441656b | ||
|
|
0799df9e66 | ||
|
|
7802166f03 | ||
|
|
3557adb064 | ||
|
|
a249e8cc96 | ||
|
|
4d973024e4 | ||
|
|
4f62e2ceb4 | ||
|
|
e4e62482ea | ||
|
|
90256d2140 | ||
|
|
7d3f707205 | ||
|
|
85ba452572 | ||
|
|
89ebf20d92 | ||
|
|
98ff51d08b | ||
|
|
ec5e65b9cf |
46
.github/actions/config/action.yml
vendored
46
.github/actions/config/action.yml
vendored
@@ -1,46 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Config'
|
||||
description: 'Read JDK Configuration Variables'
|
||||
inputs:
|
||||
var:
|
||||
description: 'The name of the variable to read'
|
||||
required: true
|
||||
outputs:
|
||||
value:
|
||||
description: 'The value of the configuration variable'
|
||||
value: ${{ steps.read-config.outputs.value }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: 'Read configuration variable from repo'
|
||||
id: read-config
|
||||
run: |
|
||||
# Extract value from configuration file
|
||||
value="$(grep -h ${{ inputs.var }}= make/conf/github-actions.conf | cut -d '=' -f 2-)"
|
||||
echo "value=$value" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
80
.github/actions/do-build/action.yml
vendored
80
.github/actions/do-build/action.yml
vendored
@@ -1,80 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Do build'
|
||||
description: 'Build the JDK using make'
|
||||
inputs:
|
||||
make-target:
|
||||
description: 'Make target(s)'
|
||||
required: true
|
||||
platform:
|
||||
description: 'Platform name'
|
||||
required: true
|
||||
debug-suffix:
|
||||
description: 'File name suffix denoting debug level, possibly empty'
|
||||
required: false
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: 'Build'
|
||||
id: build
|
||||
run: >
|
||||
make LOG=info ${{ inputs.make-target }}
|
||||
|| bash ./.github/scripts/gen-build-failure-report.sh "$GITHUB_STEP_SUMMARY"
|
||||
shell: bash
|
||||
|
||||
- name: 'Check for failure'
|
||||
id: check
|
||||
run: |
|
||||
# Check for failure marker file
|
||||
build_dir="$(ls -d build/*)"
|
||||
if [[ -e $build_dir/build-failure ]]; then
|
||||
# Collect relevant log files
|
||||
mkdir failure-logs
|
||||
cp \
|
||||
$build_dir/spec.gmk \
|
||||
$build_dir/build.log \
|
||||
$build_dir/configure.log \
|
||||
$build_dir/make-support/failure-summary.log \
|
||||
$build_dir/make-support/failure-logs/* \
|
||||
failure-logs/ 2> /dev/null || true
|
||||
echo 'failure=true' >> $GITHUB_OUTPUT
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: 'Upload build logs'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: failure-logs-${{ inputs.platform }}${{ inputs.debug-suffix }}
|
||||
path: failure-logs
|
||||
if: steps.check.outputs.failure == 'true'
|
||||
|
||||
# This is the best way I found to abort the job with an error message
|
||||
- name: 'Notify about build failures'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: core.setFailed('Build failed. See summary for details.')
|
||||
if: steps.check.outputs.failure == 'true'
|
||||
109
.github/actions/get-bootjdk/action.yml
vendored
109
.github/actions/get-bootjdk/action.yml
vendored
@@ -1,109 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Get BootJDK'
|
||||
description: 'Download the BootJDK from cache or source location'
|
||||
inputs:
|
||||
platform:
|
||||
description: 'Platform'
|
||||
required: true
|
||||
outputs:
|
||||
path:
|
||||
description: 'Path to the installed BootJDK'
|
||||
value: ${{ steps.path-name.outputs.path }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: 'Determine platform prefix'
|
||||
id: platform-prefix
|
||||
run: |
|
||||
# Convert platform name to upper case
|
||||
platform_prefix="$(echo ${{ inputs.platform }} | tr [a-z-] [A-Z_])"
|
||||
echo "value=$platform_prefix" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
|
||||
- name: 'Get URL configuration'
|
||||
id: url
|
||||
uses: ./.github/actions/config
|
||||
with:
|
||||
var: ${{ steps.platform-prefix.outputs.value}}_BOOT_JDK_URL
|
||||
|
||||
- name: 'Get SHA256 configuration'
|
||||
id: sha256
|
||||
uses: ./.github/actions/config
|
||||
with:
|
||||
var: ${{ steps.platform-prefix.outputs.value}}_BOOT_JDK_SHA256
|
||||
|
||||
- name: 'Get file extension configuration'
|
||||
id: ext
|
||||
uses: ./.github/actions/config
|
||||
with:
|
||||
var: ${{ steps.platform-prefix.outputs.value}}_BOOT_JDK_EXT
|
||||
|
||||
- name: 'Check cache for BootJDK'
|
||||
id: get-cached-bootjdk
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: bootjdk/jdk
|
||||
key: boot-jdk-${{ inputs.platform }}-${{ steps.sha256.outputs.value }}
|
||||
|
||||
# macOS is missing sha256sum
|
||||
- name: 'Install sha256sum'
|
||||
run: |
|
||||
# Run Homebrew installation
|
||||
brew install coreutils
|
||||
shell: bash
|
||||
if: steps.get-cached-bootjdk.outputs.cache-hit != 'true' && runner.os == 'macOS'
|
||||
|
||||
- name: 'Download BootJDK'
|
||||
run: |
|
||||
# Download BootJDK and verify checksum
|
||||
mkdir -p bootjdk/jdk
|
||||
mkdir -p bootjdk/unpacked
|
||||
wget --progress=dot:mega -O bootjdk/jdk.${{ steps.ext.outputs.value }} '${{ steps.url.outputs.value }}'
|
||||
echo '${{ steps.sha256.outputs.value }} bootjdk/jdk.${{ steps.ext.outputs.value }}' | sha256sum -c >/dev/null -
|
||||
shell: bash
|
||||
if: steps.get-cached-bootjdk.outputs.cache-hit != 'true'
|
||||
|
||||
- name: 'Unpack BootJDK'
|
||||
run: |
|
||||
# Unpack the BootJDK and move files to a common location
|
||||
if [[ '${{ steps.ext.outputs.value }}' == 'tar.gz' ]]; then
|
||||
tar -xf bootjdk/jdk.${{ steps.ext.outputs.value }} -C bootjdk/unpacked
|
||||
else
|
||||
unzip -q bootjdk/jdk.${{ steps.ext.outputs.value }} -d bootjdk/unpacked
|
||||
fi
|
||||
jdk_root="$(dirname $(find bootjdk/unpacked -name bin -type d))"
|
||||
mv "$jdk_root"/* bootjdk/jdk/
|
||||
shell: bash
|
||||
if: steps.get-cached-bootjdk.outputs.cache-hit != 'true'
|
||||
|
||||
- name: 'Export path to where BootJDK is installed'
|
||||
id: path-name
|
||||
run: |
|
||||
# Export the path
|
||||
echo 'path=bootjdk/jdk' >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
109
.github/actions/get-bundles/action.yml
vendored
109
.github/actions/get-bundles/action.yml
vendored
@@ -1,109 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Get bundles'
|
||||
description: 'Download resulting JDK bundles'
|
||||
inputs:
|
||||
platform:
|
||||
description: 'Platform name'
|
||||
required: true
|
||||
debug-suffix:
|
||||
description: 'File name suffix denoting debug level, possibly empty'
|
||||
required: false
|
||||
outputs:
|
||||
jdk-path:
|
||||
description: 'Path to the installed JDK bundle'
|
||||
value: ${{ steps.path-name.outputs.jdk }}
|
||||
symbols-path:
|
||||
description: 'Path to the installed symbols bundle'
|
||||
value: ${{ steps.path-name.outputs.symbols }}
|
||||
tests-path:
|
||||
description: 'Path to the installed tests bundle'
|
||||
value: ${{ steps.path-name.outputs.tests }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: 'Download bundles artifact'
|
||||
id: download-bundles
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }}
|
||||
path: bundles
|
||||
continue-on-error: true
|
||||
|
||||
- name: 'Download bundles artifact (retry)'
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }}
|
||||
path: bundles
|
||||
if: steps.download-bundles.outcome == 'failure'
|
||||
|
||||
- name: 'Unpack bundles'
|
||||
run: |
|
||||
if [[ -e bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.zip ]]; then
|
||||
echo 'Unpacking jdk bundle...'
|
||||
mkdir -p bundles/jdk
|
||||
unzip -q bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.zip -d bundles/jdk
|
||||
fi
|
||||
|
||||
if [[ -e bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz ]]; then
|
||||
echo 'Unpacking jdk bundle...'
|
||||
mkdir -p bundles/jdk
|
||||
tar -xf bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz -C bundles/jdk
|
||||
fi
|
||||
|
||||
if [[ -e bundles/symbols-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz ]]; then
|
||||
echo 'Unpacking symbols bundle...'
|
||||
mkdir -p bundles/symbols
|
||||
tar -xf bundles/symbols-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz -C bundles/symbols
|
||||
fi
|
||||
|
||||
if [[ -e bundles/tests-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz ]]; then
|
||||
echo 'Unpacking tests bundle...'
|
||||
mkdir -p bundles/tests
|
||||
tar -xf bundles/tests-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz -C bundles/tests
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: 'Export paths to where bundles are installed'
|
||||
id: path-name
|
||||
run: |
|
||||
# Export the paths
|
||||
|
||||
jdk_dir="$GITHUB_WORKSPACE/$(dirname $(find bundles/jdk -name bin -type d))"
|
||||
symbols_dir="$GITHUB_WORKSPACE/$(dirname $(find bundles/symbols -name bin -type d))"
|
||||
tests_dir="$GITHUB_WORKSPACE/bundles/tests"
|
||||
|
||||
if [[ '${{ runner.os }}' == 'Windows' ]]; then
|
||||
jdk_dir="$(cygpath $jdk_dir)"
|
||||
symbols_dir="$(cygpath $symbols_dir)"
|
||||
tests_dir="$(cygpath $tests_dir)"
|
||||
fi
|
||||
|
||||
echo "jdk=$jdk_dir" >> $GITHUB_OUTPUT
|
||||
echo "symbols=$symbols_dir" >> $GITHUB_OUTPUT
|
||||
echo "tests=$tests_dir" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
54
.github/actions/get-gtest/action.yml
vendored
54
.github/actions/get-gtest/action.yml
vendored
@@ -1,54 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Get GTest'
|
||||
description: 'Download GTest source'
|
||||
outputs:
|
||||
path:
|
||||
description: 'Path to the installed GTest'
|
||||
value: ${{ steps.path-name.outputs.path }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: 'Get GTest version configuration'
|
||||
id: version
|
||||
uses: ./.github/actions/config
|
||||
with:
|
||||
var: GTEST_VERSION
|
||||
|
||||
- name: 'Checkout GTest source'
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: google/googletest
|
||||
ref: 'release-${{ steps.version.outputs.value }}'
|
||||
path: gtest
|
||||
|
||||
- name: 'Export path to where GTest is installed'
|
||||
id: path-name
|
||||
run: |
|
||||
# Export the path
|
||||
echo 'path=gtest' >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
72
.github/actions/get-jtreg/action.yml
vendored
72
.github/actions/get-jtreg/action.yml
vendored
@@ -1,72 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Get JTReg'
|
||||
description: 'Download JTReg from cache or source location'
|
||||
outputs:
|
||||
path:
|
||||
description: 'Path to the installed JTReg'
|
||||
value: ${{ steps.path-name.outputs.path }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: 'Get JTReg version configuration'
|
||||
id: version
|
||||
uses: ./.github/actions/config
|
||||
with:
|
||||
var: JTREG_VERSION
|
||||
|
||||
- name: 'Check cache for JTReg'
|
||||
id: get-cached-jtreg
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: jtreg/installed
|
||||
key: jtreg-${{ steps.version.outputs.value }}
|
||||
|
||||
- name: 'Checkout the JTReg source'
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: openjdk/jtreg
|
||||
ref: jtreg-${{ steps.version.outputs.value }}
|
||||
path: jtreg/src
|
||||
if: steps.get-cached-jtreg.outputs.cache-hit != 'true'
|
||||
|
||||
- name: 'Build JTReg'
|
||||
run: |
|
||||
# Build JTReg and move files to the proper locations
|
||||
bash make/build.sh --jdk "$JAVA_HOME_11_X64"
|
||||
mkdir ../installed
|
||||
mv build/images/jtreg/* ../installed
|
||||
working-directory: jtreg/src
|
||||
shell: bash
|
||||
if: steps.get-cached-jtreg.outputs.cache-hit != 'true'
|
||||
|
||||
- name: 'Export path to where JTReg is installed'
|
||||
id: path-name
|
||||
run: |
|
||||
# Export the path
|
||||
echo 'path=jtreg/installed' >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
44
.github/actions/get-msys2/action.yml
vendored
44
.github/actions/get-msys2/action.yml
vendored
@@ -1,44 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Get MSYS2'
|
||||
description: 'Download MSYS2 and prepare a Windows host'
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: 'Install MSYS2'
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
install: 'autoconf tar unzip zip make'
|
||||
path-type: minimal
|
||||
location: msys2
|
||||
|
||||
# We can't run bash until this is completed, so stick with pwsh
|
||||
- name: 'Set MSYS2 path'
|
||||
run: |
|
||||
# Prepend msys2/msys64/usr/bin to the PATH
|
||||
echo "$env:GITHUB_WORKSPACE/msys2/msys64/usr/bin" >> $env:GITHUB_PATH
|
||||
shell: pwsh
|
||||
77
.github/actions/upload-bundles/action.yml
vendored
77
.github/actions/upload-bundles/action.yml
vendored
@@ -1,77 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Upload bundles'
|
||||
description: 'Upload resulting JDK bundles'
|
||||
inputs:
|
||||
platform:
|
||||
description: 'Platform name'
|
||||
required: true
|
||||
debug-suffix:
|
||||
description: 'File name suffix denoting debug level, possibly empty'
|
||||
required: false
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
|
||||
- name: 'Determine bundle names'
|
||||
id: bundles
|
||||
run: |
|
||||
# Rename bundles to consistent names
|
||||
jdk_bundle_zip="$(ls build/*/bundles/jdk-*_bin${{ inputs.debug-suffix }}.zip 2> /dev/null || true)"
|
||||
jdk_bundle_tar_gz="$(ls build/*/bundles/jdk-*_bin${{ inputs.debug-suffix }}.tar.gz 2> /dev/null || true)"
|
||||
symbols_bundle="$(ls build/*/bundles/jdk-*_bin${{ inputs.debug-suffix }}-symbols.tar.gz 2> /dev/null || true)"
|
||||
tests_bundle="$(ls build/*/bundles/jdk-*_bin-tests${{ inputs.debug-suffix }}.tar.gz 2> /dev/null || true)"
|
||||
|
||||
mkdir bundles
|
||||
|
||||
if [[ "$jdk_bundle_zip" != "" ]]; then
|
||||
mv "$jdk_bundle_zip" "bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.zip"
|
||||
fi
|
||||
if [[ "$jdk_bundle_tar_gz" != "" ]]; then
|
||||
mv "$jdk_bundle_tar_gz" "bundles/jdk-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz"
|
||||
fi
|
||||
if [[ "$symbols_bundle" != "" ]]; then
|
||||
mv "$symbols_bundle" "bundles/symbols-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz"
|
||||
fi
|
||||
if [[ "$tests_bundle" != "" ]]; then
|
||||
mv "$tests_bundle" "bundles/tests-${{ inputs.platform }}${{ inputs.debug-suffix }}.tar.gz"
|
||||
fi
|
||||
|
||||
if [[ "$jdk_bundle_zip$jdk_bundle_tar_gz$symbols_bundle$tests_bundle" != "" ]]; then
|
||||
echo 'bundles-found=true' >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo 'bundles-found=false' >> $GITHUB_OUTPUT
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
- name: 'Upload bundles artifact'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }}
|
||||
path: bundles
|
||||
retention-days: 1
|
||||
if: steps.bundles.outputs.bundles-found == 'true'
|
||||
51
.github/scripts/gen-build-failure-report.sh
vendored
51
.github/scripts/gen-build-failure-report.sh
vendored
@@ -1,51 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
GITHUB_STEP_SUMMARY="$1"
|
||||
BUILD_DIR="$(ls -d build/*)"
|
||||
|
||||
# Send signal to the do-build action that we failed
|
||||
touch "$BUILD_DIR/build-failure"
|
||||
|
||||
(
|
||||
echo '### :boom: Build failure summary'
|
||||
echo ''
|
||||
echo 'The build failed. Here follows the failure summary from the build.'
|
||||
echo '<details><summary><b>View build failure summary</b></summary>'
|
||||
echo ''
|
||||
echo '```'
|
||||
if [[ -f "$BUILD_DIR/make-support/failure-summary.log" ]]; then
|
||||
cat "$BUILD_DIR/make-support/failure-summary.log"
|
||||
else
|
||||
echo "Failure summary ($BUILD_DIR/make-support/failure-summary.log) not found"
|
||||
fi
|
||||
echo '```'
|
||||
echo '</details>'
|
||||
echo ''
|
||||
|
||||
echo ''
|
||||
echo ':arrow_right: To see the entire test log, click the job in the list to the left. To download logs, see the `failure-logs` [artifact above](#artifacts).'
|
||||
) >> $GITHUB_STEP_SUMMARY
|
||||
92
.github/scripts/gen-test-results.sh
vendored
92
.github/scripts/gen-test-results.sh
vendored
@@ -1,92 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
GITHUB_STEP_SUMMARY="$1"
|
||||
|
||||
test_suite_name=$(cat build/run-test-prebuilt/test-support/test-last-ids.txt)
|
||||
results_dir=build/run-test-prebuilt/test-results/$test_suite_name/text
|
||||
report_dir=build/run-test-prebuilt/test-support/$test_suite_name
|
||||
|
||||
failures=$(sed -E -e 's/(.*)\.(java|sh)/\1/' -e '/^#/d' $results_dir/newfailures.txt 2> /dev/null || true)
|
||||
errors=$(sed -E -e 's/(.*)\.(java|sh)/\1/' -e '/^#/d' $results_dir/other_errors.txt 2> /dev/null || true)
|
||||
|
||||
if [[ "$failures" = "" && "$errors" = "" ]]; then
|
||||
# If we have nothing to report, exit this step now
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "### Test output for failed tests" >> $GITHUB_STEP_SUMMARY
|
||||
for test in $failures $errors; do
|
||||
anchor="$(echo "$test" | tr [A-Z/] [a-z_])"
|
||||
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)
|
||||
echo "#### <a id="$anchor">$test"
|
||||
|
||||
echo '<details><summary>View test results</summary>'
|
||||
echo ''
|
||||
echo '```'
|
||||
if [[ -f "$report_file" ]]; then
|
||||
cat "$report_file"
|
||||
else
|
||||
echo "Error: Result file $report_file not found"
|
||||
fi
|
||||
echo '```'
|
||||
echo '</details>'
|
||||
echo ''
|
||||
|
||||
if [[ "$hs_err_files" != "" ]]; then
|
||||
echo '<details><summary>View HotSpot error log</summary>'
|
||||
echo ''
|
||||
for hs_err in $hs_err_files; do
|
||||
echo '```'
|
||||
echo "$hs_err:"
|
||||
echo ''
|
||||
cat "$hs_err"
|
||||
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
|
||||
# Trim it down if so.
|
||||
summary_size=$(wc -c < $GITHUB_STEP_SUMMARY)
|
||||
if [[ $summary_size -gt 1000000 ]]; then
|
||||
# Trim to below 1024 kB, and cut off after the last detail group
|
||||
head -c 1000000 $GITHUB_STEP_SUMMARY | tac | sed -n -e '/<\/details>/,$ p' | tac > $GITHUB_STEP_SUMMARY.tmp
|
||||
mv $GITHUB_STEP_SUMMARY.tmp $GITHUB_STEP_SUMMARY
|
||||
(
|
||||
echo ''
|
||||
echo ':x: **WARNING: Summary is too large and has been truncated.**'
|
||||
echo ''
|
||||
) >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
echo ':arrow_right: To see the entire test log, click the job in the list to the left.' >> $GITHUB_STEP_SUMMARY
|
||||
70
.github/scripts/gen-test-summary.sh
vendored
70
.github/scripts/gen-test-summary.sh
vendored
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
GITHUB_STEP_SUMMARY="$1"
|
||||
GITHUB_OUTPUT="$2"
|
||||
|
||||
test_suite_name=$(cat build/run-test-prebuilt/test-support/test-last-ids.txt)
|
||||
results_dir=build/run-test-prebuilt/test-results/$test_suite_name/text
|
||||
|
||||
if [[ ! -f build/run-test-prebuilt/make-support/exit-with-error ]]; then
|
||||
# There were no failures, exit now
|
||||
exit
|
||||
fi
|
||||
|
||||
failures=$(sed -E -e 's/(.*)\.(java|sh)/\1/' -e '/^#/d' $results_dir/newfailures.txt 2> /dev/null || true)
|
||||
errors=$(sed -E -e 's/(.*)\.(java|sh)/\1/' -e '/^#/d' $results_dir/other_errors.txt 2> /dev/null || true)
|
||||
failure_count=$(echo $failures | wc -w || true)
|
||||
error_count=$(echo $errors | wc -w || true)
|
||||
|
||||
if [[ "$failures" = "" && "$errors" = "" ]]; then
|
||||
# We know something went wrong, but not what
|
||||
echo 'error-message=Unspecified test suite failure. Please see log for job for details.' >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo 'failure=true' >> $GITHUB_OUTPUT
|
||||
echo "error-message=Test run reported $failure_count test failure(s) and $error_count error(s). See summary for details." >> $GITHUB_OUTPUT
|
||||
|
||||
echo '### :boom: Test failures summary' >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
if [[ "$failures" != "" ]]; then
|
||||
echo '' >> $GITHUB_STEP_SUMMARY
|
||||
echo 'These tests reported failure:' >> $GITHUB_STEP_SUMMARY
|
||||
for test in $failures; do
|
||||
anchor="$(echo "$test" | tr [A-Z/] [a-z_])"
|
||||
echo "* [$test](#user-content-$anchor)"
|
||||
done >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
if [[ "$errors" != "" ]]; then
|
||||
echo '' >> $GITHUB_STEP_SUMMARY
|
||||
echo 'These tests reported errors:' >> $GITHUB_STEP_SUMMARY
|
||||
for test in $errors; do
|
||||
anchor="$(echo "$test" | tr [A-Z/] [a-z_])"
|
||||
echo "* [$test](#user-content-$anchor)"
|
||||
done >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
184
.github/workflows/build-cross-compile.yml
vendored
184
.github/workflows/build-cross-compile.yml
vendored
@@ -1,184 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Build (cross-compile)'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
gcc-major-version:
|
||||
required: true
|
||||
type: string
|
||||
apt-gcc-version:
|
||||
required: true
|
||||
type: string
|
||||
apt-gcc-cross-version:
|
||||
required: true
|
||||
type: string
|
||||
extra-conf-options:
|
||||
required: false
|
||||
type: string
|
||||
configure-arguments:
|
||||
required: false
|
||||
type: string
|
||||
make-arguments:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-cross-compile:
|
||||
name: build
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target-cpu:
|
||||
- aarch64
|
||||
- arm
|
||||
- s390x
|
||||
- ppc64le
|
||||
- riscv64
|
||||
include:
|
||||
- target-cpu: aarch64
|
||||
gnu-arch: aarch64
|
||||
debian-arch: arm64
|
||||
debian-repository: https://httpredir.debian.org/debian/
|
||||
debian-version: bullseye
|
||||
- target-cpu: arm
|
||||
gnu-arch: arm
|
||||
debian-arch: armhf
|
||||
debian-repository: https://httpredir.debian.org/debian/
|
||||
debian-version: bullseye
|
||||
gnu-abi: eabihf
|
||||
- target-cpu: s390x
|
||||
gnu-arch: s390x
|
||||
debian-arch: s390x
|
||||
debian-repository: https://httpredir.debian.org/debian/
|
||||
debian-version: bullseye
|
||||
- target-cpu: ppc64le
|
||||
gnu-arch: powerpc64le
|
||||
debian-arch: ppc64el
|
||||
debian-repository: https://httpredir.debian.org/debian/
|
||||
debian-version: bullseye
|
||||
- target-cpu: riscv64
|
||||
gnu-arch: riscv64
|
||||
debian-arch: riscv64
|
||||
debian-repository: https://deb.debian.org/debian-ports
|
||||
debian-keyring: /usr/share/keyrings/debian-ports-archive-keyring.gpg
|
||||
debian-version: sid
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: 'Get the BootJDK'
|
||||
id: bootjdk
|
||||
uses: ./.github/actions/get-bootjdk
|
||||
with:
|
||||
platform: linux-x64
|
||||
|
||||
# Use linux-x64 JDK bundle as build JDK
|
||||
- name: 'Get build JDK'
|
||||
id: buildjdk
|
||||
uses: ./.github/actions/get-bundles
|
||||
with:
|
||||
platform: linux-x64
|
||||
|
||||
# Upgrading apt to solve libc6 installation bugs, see JDK-8260460.
|
||||
- name: 'Install toolchain and dependencies'
|
||||
run: |
|
||||
# Install dependencies using apt-get
|
||||
sudo apt-get update
|
||||
sudo apt-get install --only-upgrade apt
|
||||
sudo apt-get install \
|
||||
gcc-${{ inputs.gcc-major-version }}=${{ inputs.apt-gcc-version }} \
|
||||
g++-${{ inputs.gcc-major-version }}=${{ inputs.apt-gcc-version }} \
|
||||
gcc-${{ inputs.gcc-major-version }}-${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}=${{ inputs.apt-gcc-cross-version }} \
|
||||
g++-${{ inputs.gcc-major-version }}-${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}=${{ inputs.apt-gcc-cross-version }} \
|
||||
libxrandr-dev libxtst-dev libcups2-dev libasound2-dev \
|
||||
debian-ports-archive-keyring
|
||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${{ inputs.gcc-major-version }} 100 --slave /usr/bin/g++ g++ /usr/bin/g++-${{ inputs.gcc-major-version }}
|
||||
|
||||
- name: 'Check cache for sysroot'
|
||||
id: get-cached-sysroot
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: sysroot
|
||||
key: sysroot-${{ matrix.debian-arch }}-${{ hashFiles('./.github/workflows/build-cross-compile.yml') }}
|
||||
|
||||
- name: 'Install sysroot dependencies'
|
||||
run: sudo apt-get install debootstrap qemu-user-static
|
||||
if: steps.get-cached-sysroot.outputs.cache-hit != 'true'
|
||||
|
||||
- name: 'Create sysroot'
|
||||
run: >
|
||||
sudo debootstrap
|
||||
--arch=${{ matrix.debian-arch }}
|
||||
--verbose
|
||||
--include=fakeroot,symlinks,build-essential,libx11-dev,libxext-dev,libxrender-dev,libxrandr-dev,libxtst-dev,libxt-dev,libcups2-dev,libfontconfig1-dev,libasound2-dev,libfreetype6-dev,libpng-dev
|
||||
--resolve-deps
|
||||
$(test -n "${{ matrix.debian-keyring }}" && echo "--keyring=${{ matrix.debian-keyring }}")
|
||||
${{ matrix.debian-version }}
|
||||
sysroot
|
||||
${{ matrix.debian-repository }}
|
||||
if: steps.get-cached-sysroot.outputs.cache-hit != 'true'
|
||||
|
||||
- name: 'Prepare sysroot'
|
||||
run: |
|
||||
# Prepare sysroot and remove unused files to minimize cache
|
||||
sudo chroot sysroot symlinks -cr .
|
||||
sudo chown ${USER} -R sysroot
|
||||
rm -rf sysroot/{dev,proc,run,sys,var}
|
||||
rm -rf sysroot/usr/{sbin,bin,share}
|
||||
rm -rf sysroot/usr/lib/{apt,udev,systemd}
|
||||
if: steps.get-cached-sysroot.outputs.cache-hit != 'true'
|
||||
|
||||
- name: 'Configure'
|
||||
run: >
|
||||
bash configure
|
||||
--with-conf-name=linux-${{ matrix.target-cpu }}
|
||||
--with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA}
|
||||
--with-boot-jdk=${{ steps.bootjdk.outputs.path }}
|
||||
--with-zlib=system
|
||||
--enable-debug
|
||||
--disable-precompiled-headers
|
||||
--openjdk-target=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}
|
||||
--with-sysroot=sysroot
|
||||
--with-build-jdk=${{ steps.buildjdk.outputs.jdk-path }}
|
||||
--with-jmod-compress=zip-1
|
||||
CC=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-gcc-${{ inputs.gcc-major-version }}
|
||||
CXX=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-g++-${{ inputs.gcc-major-version }}
|
||||
${{ inputs.extra-conf-options }} ${{ inputs.configure-arguments }} || (
|
||||
echo "Dumping config.log:" &&
|
||||
cat config.log &&
|
||||
exit 1)
|
||||
|
||||
- name: 'Build'
|
||||
id: build
|
||||
uses: ./.github/actions/do-build
|
||||
with:
|
||||
make-target: 'hotspot ${{ inputs.make-arguments }}'
|
||||
platform: linux-${{ matrix.target-cpu }}
|
||||
149
.github/workflows/build-linux.yml
vendored
149
.github/workflows/build-linux.yml
vendored
@@ -1,149 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Build (linux)'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
platform:
|
||||
required: true
|
||||
type: string
|
||||
extra-conf-options:
|
||||
required: false
|
||||
type: string
|
||||
make-target:
|
||||
required: false
|
||||
type: string
|
||||
default: 'product-bundles test-bundles'
|
||||
debug-levels:
|
||||
required: false
|
||||
type: string
|
||||
default: '[ "debug", "release" ]'
|
||||
gcc-major-version:
|
||||
required: true
|
||||
type: string
|
||||
gcc-package-suffix:
|
||||
required: false
|
||||
type: string
|
||||
default: ''
|
||||
apt-gcc-version:
|
||||
required: true
|
||||
type: string
|
||||
apt-architecture:
|
||||
required: false
|
||||
type: string
|
||||
apt-extra-packages:
|
||||
required: false
|
||||
type: string
|
||||
configure-arguments:
|
||||
required: false
|
||||
type: string
|
||||
make-arguments:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
name: build
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
debug-level: ${{ fromJSON(inputs.debug-levels) }}
|
||||
include:
|
||||
- debug-level: debug
|
||||
flags: --with-debug-level=fastdebug
|
||||
suffix: -debug
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: 'Get the BootJDK'
|
||||
id: bootjdk
|
||||
uses: ./.github/actions/get-bootjdk
|
||||
with:
|
||||
platform: linux-x64
|
||||
|
||||
- name: 'Get JTReg'
|
||||
id: jtreg
|
||||
uses: ./.github/actions/get-jtreg
|
||||
|
||||
- name: 'Get GTest'
|
||||
id: gtest
|
||||
uses: ./.github/actions/get-gtest
|
||||
|
||||
- name: 'Set architecture'
|
||||
id: arch
|
||||
run: |
|
||||
# Set a proper suffix for packages if using a different architecture
|
||||
if [[ '${{ inputs.apt-architecture }}' != '' ]]; then
|
||||
echo 'suffix=:${{ inputs.apt-architecture }}' >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
# Upgrading apt to solve libc6 installation bugs, see JDK-8260460.
|
||||
- name: 'Install toolchain and dependencies'
|
||||
run: |
|
||||
# Install dependencies using apt-get
|
||||
if [[ '${{ inputs.apt-architecture }}' != '' ]]; then
|
||||
sudo dpkg --add-architecture ${{ inputs.apt-architecture }}
|
||||
fi
|
||||
sudo apt-get update
|
||||
sudo apt-get install --only-upgrade apt
|
||||
sudo apt-get install gcc-${{ inputs.gcc-major-version }}${{ inputs.gcc-package-suffix }}=${{ inputs.apt-gcc-version }} g++-${{ inputs.gcc-major-version }}${{ inputs.gcc-package-suffix }}=${{ inputs.apt-gcc-version }} libxrandr-dev${{ steps.arch.outputs.suffix }} libxtst-dev${{ steps.arch.outputs.suffix }} libcups2-dev${{ steps.arch.outputs.suffix }} libasound2-dev${{ steps.arch.outputs.suffix }} ${{ inputs.apt-extra-packages }}
|
||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${{ inputs.gcc-major-version }} 100 --slave /usr/bin/g++ g++ /usr/bin/g++-${{ inputs.gcc-major-version }}
|
||||
|
||||
- name: 'Configure'
|
||||
run: >
|
||||
bash configure
|
||||
--with-conf-name=${{ inputs.platform }}
|
||||
${{ matrix.flags }}
|
||||
--with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA}
|
||||
--with-boot-jdk=${{ steps.bootjdk.outputs.path }}
|
||||
--with-jtreg=${{ steps.jtreg.outputs.path }}
|
||||
--with-gtest=${{ steps.gtest.outputs.path }}
|
||||
--enable-jtreg-failure-handler
|
||||
--with-zlib=system
|
||||
--with-jmod-compress=zip-1
|
||||
${{ inputs.extra-conf-options }} ${{ inputs.configure-arguments }} || (
|
||||
echo "Dumping config.log:" &&
|
||||
cat config.log &&
|
||||
exit 1)
|
||||
|
||||
- name: 'Build'
|
||||
id: build
|
||||
uses: ./.github/actions/do-build
|
||||
with:
|
||||
make-target: '${{ inputs.make-target }} ${{ inputs.make-arguments }}'
|
||||
platform: ${{ inputs.platform }}
|
||||
debug-suffix: '${{ matrix.suffix }}'
|
||||
|
||||
- name: 'Upload bundles'
|
||||
uses: ./.github/actions/upload-bundles
|
||||
with:
|
||||
platform: ${{ inputs.platform }}
|
||||
debug-suffix: '${{ matrix.suffix }}'
|
||||
124
.github/workflows/build-macos.yml
vendored
124
.github/workflows/build-macos.yml
vendored
@@ -1,124 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Build (macos)'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
platform:
|
||||
required: true
|
||||
type: string
|
||||
extra-conf-options:
|
||||
required: false
|
||||
type: string
|
||||
make-target:
|
||||
required: false
|
||||
type: string
|
||||
default: 'product-bundles test-bundles'
|
||||
debug-levels:
|
||||
required: false
|
||||
type: string
|
||||
default: '[ "debug", "release" ]'
|
||||
xcode-toolset-version:
|
||||
required: true
|
||||
type: string
|
||||
configure-arguments:
|
||||
required: false
|
||||
type: string
|
||||
make-arguments:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
build-macos:
|
||||
name: build
|
||||
runs-on: macos-11
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
debug-level: ${{ fromJSON(inputs.debug-levels) }}
|
||||
include:
|
||||
- debug-level: debug
|
||||
flags: --with-debug-level=fastdebug
|
||||
suffix: -debug
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: 'Get the BootJDK'
|
||||
id: bootjdk
|
||||
uses: ./.github/actions/get-bootjdk
|
||||
with:
|
||||
platform: macos-x64
|
||||
|
||||
- name: 'Get JTReg'
|
||||
id: jtreg
|
||||
uses: ./.github/actions/get-jtreg
|
||||
|
||||
- name: 'Get GTest'
|
||||
id: gtest
|
||||
uses: ./.github/actions/get-gtest
|
||||
|
||||
- name: 'Install toolchain and dependencies'
|
||||
run: |
|
||||
# Run Homebrew installation and xcode-select
|
||||
brew install make
|
||||
sudo xcode-select --switch /Applications/Xcode_${{ inputs.xcode-toolset-version }}.app/Contents/Developer
|
||||
# This will make GNU make available as 'make' and not only as 'gmake'
|
||||
echo '/usr/local/opt/make/libexec/gnubin' >> $GITHUB_PATH
|
||||
|
||||
- name: 'Configure'
|
||||
run: >
|
||||
bash configure
|
||||
--with-conf-name=${{ inputs.platform }}
|
||||
${{ matrix.flags }}
|
||||
--with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA}
|
||||
--with-boot-jdk=${{ steps.bootjdk.outputs.path }}
|
||||
--with-jtreg=${{ steps.jtreg.outputs.path }}
|
||||
--with-gtest=${{ steps.gtest.outputs.path }}
|
||||
--enable-jtreg-failure-handler
|
||||
--with-zlib=system
|
||||
--with-jmod-compress=zip-1
|
||||
${{ inputs.extra-conf-options }} ${{ inputs.configure-arguments }} || (
|
||||
echo "Dumping config.log:" &&
|
||||
cat config.log &&
|
||||
exit 1)
|
||||
|
||||
- name: 'Build'
|
||||
id: build
|
||||
uses: ./.github/actions/do-build
|
||||
with:
|
||||
make-target: '${{ inputs.make-target }} ${{ inputs.make-arguments }}'
|
||||
platform: ${{ inputs.platform }}
|
||||
debug-suffix: '${{ matrix.suffix }}'
|
||||
|
||||
- name: 'Upload bundles'
|
||||
uses: ./.github/actions/upload-bundles
|
||||
with:
|
||||
platform: ${{ inputs.platform }}
|
||||
debug-suffix: '${{ matrix.suffix }}'
|
||||
141
.github/workflows/build-windows.yml
vendored
141
.github/workflows/build-windows.yml
vendored
@@ -1,141 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Build (windows)'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
platform:
|
||||
required: true
|
||||
type: string
|
||||
extra-conf-options:
|
||||
required: false
|
||||
type: string
|
||||
make-target:
|
||||
required: false
|
||||
type: string
|
||||
default: 'product-bundles test-bundles'
|
||||
debug-levels:
|
||||
required: false
|
||||
type: string
|
||||
default: '[ "debug", "release" ]'
|
||||
msvc-toolset-version:
|
||||
required: true
|
||||
type: string
|
||||
msvc-toolset-architecture:
|
||||
required: true
|
||||
type: string
|
||||
configure-arguments:
|
||||
required: false
|
||||
type: string
|
||||
make-arguments:
|
||||
required: false
|
||||
type: string
|
||||
|
||||
env:
|
||||
# These are needed to make the MSYS2 bash work properly
|
||||
MSYS2_PATH_TYPE: minimal
|
||||
CHERE_INVOKING: 1
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
name: build
|
||||
runs-on: windows-2019
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
debug-level: ${{ fromJSON(inputs.debug-levels) }}
|
||||
include:
|
||||
- debug-level: debug
|
||||
flags: --with-debug-level=fastdebug
|
||||
suffix: -debug
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: 'Get MSYS2'
|
||||
uses: ./.github/actions/get-msys2
|
||||
|
||||
- name: 'Get the BootJDK'
|
||||
id: bootjdk
|
||||
uses: ./.github/actions/get-bootjdk
|
||||
with:
|
||||
platform: windows-x64
|
||||
|
||||
- name: 'Get JTReg'
|
||||
id: jtreg
|
||||
uses: ./.github/actions/get-jtreg
|
||||
|
||||
- name: 'Get GTest'
|
||||
id: gtest
|
||||
uses: ./.github/actions/get-gtest
|
||||
|
||||
- name: 'Install toolchain and dependencies'
|
||||
run: |
|
||||
# Run Visual Studio Installer
|
||||
'/c/Program Files (x86)/Microsoft Visual Studio/Installer/vs_installer.exe' \
|
||||
modify --quiet --installPath 'C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise' \
|
||||
--add Microsoft.VisualStudio.Component.VC.${{ inputs.msvc-toolset-version }}.${{ inputs.msvc-toolset-architecture }}
|
||||
|
||||
- name: 'Configure'
|
||||
run: >
|
||||
bash configure
|
||||
--with-conf-name=${{ inputs.platform }}
|
||||
${{ matrix.flags }}
|
||||
--with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA}
|
||||
--with-boot-jdk=${{ steps.bootjdk.outputs.path }}
|
||||
--with-jtreg=${{ steps.jtreg.outputs.path }}
|
||||
--with-gtest=${{ steps.gtest.outputs.path }}
|
||||
--enable-jtreg-failure-handler
|
||||
--with-msvc-toolset-version=${{ inputs.msvc-toolset-version }}
|
||||
--with-jmod-compress=zip-1
|
||||
${{ inputs.extra-conf-options }} ${{ inputs.configure-arguments }} || (
|
||||
echo "Dumping config.log:" &&
|
||||
cat config.log &&
|
||||
exit 1)
|
||||
env:
|
||||
# We need a minimal PATH on Windows
|
||||
# Set PATH to "", so just GITHUB_PATH is included
|
||||
PATH: ''
|
||||
|
||||
- name: 'Build'
|
||||
id: build
|
||||
uses: ./.github/actions/do-build
|
||||
with:
|
||||
make-target: '${{ inputs.make-target }} ${{ inputs.make-arguments }}'
|
||||
platform: ${{ inputs.platform }}
|
||||
debug-suffix: '${{ matrix.suffix }}'
|
||||
|
||||
- name: 'Upload bundles'
|
||||
uses: ./.github/actions/upload-bundles
|
||||
with:
|
||||
platform: ${{ inputs.platform }}
|
||||
debug-suffix: '${{ matrix.suffix }}'
|
||||
387
.github/workflows/main.yml
vendored
387
.github/workflows/main.yml
vendored
@@ -1,387 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'OpenJDK GHA Sanity Checks'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- master
|
||||
- pr/*
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
platforms:
|
||||
description: 'Platform(s) to execute on (comma separated, e.g. "linux-x64, macos, aarch64")'
|
||||
required: true
|
||||
default: 'linux-x64, linux-x86, linux-x64-variants, linux-cross-compile, macos-x64, macos-aarch64, windows-x64, windows-aarch64, docs'
|
||||
configure-arguments:
|
||||
description: 'Additional configure arguments'
|
||||
required: false
|
||||
make-arguments:
|
||||
description: 'Additional make arguments'
|
||||
required: false
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
###
|
||||
### Determine platforms to include
|
||||
###
|
||||
|
||||
select:
|
||||
name: 'Select platforms'
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
linux-x64: ${{ steps.include.outputs.linux-x64 }}
|
||||
linux-x86: ${{ steps.include.outputs.linux-x86 }}
|
||||
linux-x64-variants: ${{ steps.include.outputs.linux-x64-variants }}
|
||||
linux-cross-compile: ${{ steps.include.outputs.linux-cross-compile }}
|
||||
macos-x64: ${{ steps.include.outputs.macos-x64 }}
|
||||
macos-aarch64: ${{ steps.include.outputs.macos-aarch64 }}
|
||||
windows-x64: ${{ steps.include.outputs.windows-x64 }}
|
||||
windows-aarch64: ${{ steps.include.outputs.windows-aarch64 }}
|
||||
docs: ${{ steps.include.outputs.docs }}
|
||||
|
||||
steps:
|
||||
# This function must be inlined in main.yml, or we'd be forced to checkout the repo
|
||||
- name: 'Check what jobs to run'
|
||||
id: include
|
||||
run: |
|
||||
# Determine which platform jobs to run
|
||||
|
||||
# Returns 'true' if the input platform list matches any of the platform monikers given as argument,
|
||||
# 'false' otherwise.
|
||||
# arg $1: platform name or names to look for
|
||||
function check_platform() {
|
||||
if [[ $GITHUB_EVENT_NAME == workflow_dispatch ]]; then
|
||||
input='${{ github.event.inputs.platforms }}'
|
||||
elif [[ $GITHUB_EVENT_NAME == push ]]; then
|
||||
if [[ '${{ !secrets.JDK_SUBMIT_FILTER || startsWith(github.ref, 'refs/heads/submit/') }}' == 'false' ]]; then
|
||||
# If JDK_SUBMIT_FILTER is set, and this is not a "submit/" branch, don't run anything
|
||||
>&2 echo 'JDK_SUBMIT_FILTER is set and not a "submit/" branch'
|
||||
echo 'false'
|
||||
return
|
||||
else
|
||||
input='${{ secrets.JDK_SUBMIT_PLATFORMS }}'
|
||||
fi
|
||||
fi
|
||||
|
||||
normalized_input="$(echo ,$input, | tr -d ' ')"
|
||||
if [[ "$normalized_input" == ",," ]]; then
|
||||
# For an empty input, assume all platforms should run
|
||||
echo 'true'
|
||||
return
|
||||
else
|
||||
# Check for all acceptable platform names
|
||||
for part in $* ; do
|
||||
if echo "$normalized_input" | grep -q -e ",$part," ; then
|
||||
echo 'true'
|
||||
return
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo 'false'
|
||||
}
|
||||
|
||||
echo "linux-x64=$(check_platform linux-x64 linux x64)" >> $GITHUB_OUTPUT
|
||||
echo "linux-x86=$(check_platform linux-x86 linux x86)" >> $GITHUB_OUTPUT
|
||||
echo "linux-x64-variants=$(check_platform linux-x64-variants variants)" >> $GITHUB_OUTPUT
|
||||
echo "linux-cross-compile=$(check_platform linux-cross-compile cross-compile)" >> $GITHUB_OUTPUT
|
||||
echo "macos-x64=$(check_platform macos-x64 macos x64)" >> $GITHUB_OUTPUT
|
||||
echo "macos-aarch64=$(check_platform macos-aarch64 macos aarch64)" >> $GITHUB_OUTPUT
|
||||
echo "windows-x64=$(check_platform windows-x64 windows x64)" >> $GITHUB_OUTPUT
|
||||
echo "windows-aarch64=$(check_platform windows-aarch64 windows aarch64)" >> $GITHUB_OUTPUT
|
||||
echo "docs=$(check_platform docs)" >> $GITHUB_OUTPUT
|
||||
|
||||
###
|
||||
### Build jobs
|
||||
###
|
||||
|
||||
build-linux-x64:
|
||||
name: linux-x64
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
with:
|
||||
platform: linux-x64
|
||||
gcc-major-version: '10'
|
||||
apt-gcc-version: '10.4.0-4ubuntu1~22.04'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
# The linux-x64 jdk bundle is used as buildjdk for the cross-compile job
|
||||
if: needs.select.outputs.linux-x64 == 'true' || needs.select.outputs.linux-cross-compile == 'true'
|
||||
|
||||
build-linux-x86:
|
||||
name: linux-x86
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
with:
|
||||
platform: linux-x86
|
||||
gcc-major-version: '10'
|
||||
gcc-package-suffix: '-multilib'
|
||||
apt-gcc-version: '10.4.0-4ubuntu1~22.04'
|
||||
apt-architecture: 'i386'
|
||||
# Some multilib libraries do not have proper inter-dependencies, so we have to
|
||||
# install their dependencies manually.
|
||||
apt-extra-packages: 'libfreetype6-dev:i386 libtiff-dev:i386 libcupsimage2-dev:i386 libc6-i386'
|
||||
extra-conf-options: '--with-target-bits=32'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.linux-x86 == 'true'
|
||||
|
||||
build-linux-x64-hs-nopch:
|
||||
name: linux-x64-hs-nopch
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
with:
|
||||
platform: linux-x64
|
||||
make-target: 'hotspot'
|
||||
debug-levels: '[ "debug" ]'
|
||||
gcc-major-version: '10'
|
||||
apt-gcc-version: '10.4.0-4ubuntu1~22.04'
|
||||
extra-conf-options: '--disable-precompiled-headers'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.linux-x64-variants == 'true'
|
||||
|
||||
build-linux-x64-hs-zero:
|
||||
name: linux-x64-hs-zero
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
with:
|
||||
platform: linux-x64
|
||||
make-target: 'hotspot'
|
||||
debug-levels: '[ "debug" ]'
|
||||
gcc-major-version: '10'
|
||||
apt-gcc-version: '10.4.0-4ubuntu1~22.04'
|
||||
extra-conf-options: '--with-jvm-variants=zero --disable-precompiled-headers'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.linux-x64-variants == 'true'
|
||||
|
||||
build-linux-x64-hs-minimal:
|
||||
name: linux-x64-hs-minimal
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
with:
|
||||
platform: linux-x64
|
||||
make-target: 'hotspot'
|
||||
debug-levels: '[ "debug" ]'
|
||||
gcc-major-version: '10'
|
||||
apt-gcc-version: '10.4.0-4ubuntu1~22.04'
|
||||
extra-conf-options: '--with-jvm-variants=minimal --disable-precompiled-headers'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.linux-x64-variants == 'true'
|
||||
|
||||
build-linux-x64-hs-optimized:
|
||||
name: linux-x64-hs-optimized
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
with:
|
||||
platform: linux-x64
|
||||
make-target: 'hotspot'
|
||||
# Technically this is not the "debug" level, but we can't inject a new matrix state for just this job
|
||||
debug-levels: '[ "debug" ]'
|
||||
gcc-major-version: '10'
|
||||
apt-gcc-version: '10.4.0-4ubuntu1~22.04'
|
||||
extra-conf-options: '--with-debug-level=optimized --disable-precompiled-headers'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.linux-x64-variants == 'true'
|
||||
|
||||
build-linux-cross-compile:
|
||||
name: linux-cross-compile
|
||||
needs:
|
||||
- select
|
||||
- build-linux-x64
|
||||
uses: ./.github/workflows/build-cross-compile.yml
|
||||
with:
|
||||
gcc-major-version: '10'
|
||||
apt-gcc-version: '10.4.0-4ubuntu1~22.04'
|
||||
apt-gcc-cross-version: '10.4.0-4ubuntu1~22.04cross1'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.linux-cross-compile == 'true'
|
||||
|
||||
build-macos-x64:
|
||||
name: macos-x64
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-macos.yml
|
||||
with:
|
||||
platform: macos-x64
|
||||
xcode-toolset-version: '11.7'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.macos-x64 == 'true'
|
||||
|
||||
build-macos-aarch64:
|
||||
name: macos-aarch64
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-macos.yml
|
||||
with:
|
||||
platform: macos-aarch64
|
||||
xcode-toolset-version: '12.4'
|
||||
extra-conf-options: '--openjdk-target=aarch64-apple-darwin'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.macos-aarch64 == 'true'
|
||||
|
||||
build-windows-x64:
|
||||
name: windows-x64
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-windows.yml
|
||||
with:
|
||||
platform: windows-x64
|
||||
msvc-toolset-version: '14.29'
|
||||
msvc-toolset-architecture: 'x86.x64'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.windows-x64 == 'true'
|
||||
|
||||
build-windows-aarch64:
|
||||
name: windows-aarch64
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-windows.yml
|
||||
with:
|
||||
platform: windows-aarch64
|
||||
msvc-toolset-version: '14.29'
|
||||
msvc-toolset-architecture: 'arm64'
|
||||
make-target: 'hotspot'
|
||||
extra-conf-options: '--openjdk-target=aarch64-unknown-cygwin'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.windows-aarch64 == 'true'
|
||||
|
||||
build-docs:
|
||||
name: docs
|
||||
needs: select
|
||||
uses: ./.github/workflows/build-linux.yml
|
||||
with:
|
||||
platform: linux-x64
|
||||
debug-levels: '[ "debug" ]'
|
||||
make-target: 'docs-jdk-bundles'
|
||||
# Make sure we never try to make full docs, since that would require a
|
||||
# build JDK, and we do not need the additional testing of the graphs.
|
||||
extra-conf-options: '--disable-full-docs'
|
||||
gcc-major-version: '10'
|
||||
apt-gcc-version: '10.4.0-4ubuntu1~22.04'
|
||||
configure-arguments: ${{ github.event.inputs.configure-arguments }}
|
||||
make-arguments: ${{ github.event.inputs.make-arguments }}
|
||||
if: needs.select.outputs.docs == 'true'
|
||||
|
||||
###
|
||||
### Test jobs
|
||||
###
|
||||
|
||||
test-linux-x64:
|
||||
name: linux-x64
|
||||
needs:
|
||||
- build-linux-x64
|
||||
uses: ./.github/workflows/test.yml
|
||||
with:
|
||||
platform: linux-x64
|
||||
bootjdk-platform: linux-x64
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
test-linux-x86:
|
||||
name: linux-x86
|
||||
needs:
|
||||
- build-linux-x86
|
||||
uses: ./.github/workflows/test.yml
|
||||
with:
|
||||
platform: linux-x86
|
||||
bootjdk-platform: linux-x64
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
test-macos-x64:
|
||||
name: macos-x64
|
||||
needs:
|
||||
- build-macos-x64
|
||||
uses: ./.github/workflows/test.yml
|
||||
with:
|
||||
platform: macos-x64
|
||||
bootjdk-platform: macos-x64
|
||||
runs-on: macos-11
|
||||
|
||||
test-windows-x64:
|
||||
name: windows-x64
|
||||
needs:
|
||||
- build-windows-x64
|
||||
uses: ./.github/workflows/test.yml
|
||||
with:
|
||||
platform: windows-x64
|
||||
bootjdk-platform: windows-x64
|
||||
runs-on: windows-2019
|
||||
|
||||
# Remove bundles so they are not misconstrued as binary distributions from the JDK project
|
||||
remove-bundles:
|
||||
name: 'Remove bundle artifacts'
|
||||
runs-on: ubuntu-22.04
|
||||
if: always()
|
||||
needs:
|
||||
- build-linux-x64
|
||||
- build-linux-x86
|
||||
- build-linux-x64-hs-nopch
|
||||
- build-linux-x64-hs-zero
|
||||
- build-linux-x64-hs-minimal
|
||||
- build-linux-x64-hs-optimized
|
||||
- build-linux-cross-compile
|
||||
- build-macos-x64
|
||||
- build-macos-aarch64
|
||||
- build-windows-x64
|
||||
- build-windows-aarch64
|
||||
- test-linux-x64
|
||||
- test-linux-x86
|
||||
- test-macos-x64
|
||||
- test-windows-x64
|
||||
|
||||
steps:
|
||||
# Hack to get hold of the api environment variables that are only defined for actions
|
||||
- name: 'Get API configuration'
|
||||
id: api
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: 'return { url: process.env["ACTIONS_RUNTIME_URL"], token: process.env["ACTIONS_RUNTIME_TOKEN"] }'
|
||||
|
||||
- name: 'Remove bundle artifacts'
|
||||
run: |
|
||||
# Find and remove all bundle artifacts
|
||||
ALL_ARTIFACT_URLS="$(curl -s \
|
||||
-H 'Accept: application/json;api-version=6.0-preview' \
|
||||
-H 'Authorization: Bearer ${{ fromJson(steps.api.outputs.result).token }}' \
|
||||
'${{ fromJson(steps.api.outputs.result).url }}_apis/pipelines/workflows/${{ github.run_id }}/artifacts?api-version=6.0-preview')"
|
||||
BUNDLE_ARTIFACT_URLS="$(echo "$ALL_ARTIFACT_URLS" | jq -r -c '.value | map(select(.name|startswith("bundles-"))) | .[].url')"
|
||||
for url in $BUNDLE_ARTIFACT_URLS; do
|
||||
echo "Removing $url"
|
||||
curl -s \
|
||||
-H 'Accept: application/json;api-version=6.0-preview' \
|
||||
-H 'Authorization: Bearer ${{ fromJson(steps.api.outputs.result).token }}' \
|
||||
-X DELETE "$url" \
|
||||
|| echo "Failed to remove bundle"
|
||||
done
|
||||
1717
.github/workflows/submit.yml
vendored
Normal file
1717
.github/workflows/submit.yml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
205
.github/workflows/test.yml
vendored
205
.github/workflows/test.yml
vendored
@@ -1,205 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
name: 'Run tests'
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
platform:
|
||||
required: true
|
||||
type: string
|
||||
bootjdk-platform:
|
||||
required: true
|
||||
type: string
|
||||
runs-on:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
# These are needed to make the MSYS2 bash work properly
|
||||
MSYS2_PATH_TYPE: minimal
|
||||
CHERE_INVOKING: 1
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: test
|
||||
runs-on: ${{ inputs.runs-on }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
test-name:
|
||||
- 'jdk/tier1 part 1'
|
||||
- 'jdk/tier1 part 2'
|
||||
- 'jdk/tier1 part 3'
|
||||
- 'langtools/tier1'
|
||||
- 'hs/tier1 common'
|
||||
- 'hs/tier1 compiler'
|
||||
- 'hs/tier1 gc'
|
||||
- 'hs/tier1 runtime'
|
||||
- 'hs/tier1 serviceability'
|
||||
|
||||
include:
|
||||
- test-name: 'jdk/tier1 part 1'
|
||||
test-suite: 'test/jdk/:tier1_part1'
|
||||
|
||||
- test-name: 'jdk/tier1 part 2'
|
||||
test-suite: 'test/jdk/:tier1_part2'
|
||||
|
||||
- test-name: 'jdk/tier1 part 3'
|
||||
test-suite: 'test/jdk/:tier1_part3'
|
||||
|
||||
- test-name: 'langtools/tier1'
|
||||
test-suite: 'test/langtools/:tier1'
|
||||
|
||||
- test-name: 'hs/tier1 common'
|
||||
test-suite: 'test/hotspot/jtreg/:tier1_common'
|
||||
debug-suffix: -debug
|
||||
|
||||
- test-name: 'hs/tier1 compiler'
|
||||
test-suite: 'test/hotspot/jtreg/:tier1_compiler'
|
||||
debug-suffix: -debug
|
||||
|
||||
- test-name: 'hs/tier1 gc'
|
||||
test-suite: 'test/hotspot/jtreg/:tier1_gc'
|
||||
debug-suffix: -debug
|
||||
|
||||
- test-name: 'hs/tier1 runtime'
|
||||
test-suite: 'test/hotspot/jtreg/:tier1_runtime'
|
||||
debug-suffix: -debug
|
||||
|
||||
- test-name: 'hs/tier1 serviceability'
|
||||
test-suite: 'test/hotspot/jtreg/:tier1_serviceability'
|
||||
debug-suffix: -debug
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: 'Get MSYS2'
|
||||
uses: ./.github/actions/get-msys2
|
||||
if: runner.os == 'Windows'
|
||||
|
||||
- name: 'Get the BootJDK'
|
||||
id: bootjdk
|
||||
uses: ./.github/actions/get-bootjdk
|
||||
with:
|
||||
platform: ${{ inputs.bootjdk-platform }}
|
||||
|
||||
- name: 'Get JTReg'
|
||||
id: jtreg
|
||||
uses: ./.github/actions/get-jtreg
|
||||
|
||||
- name: 'Get bundles'
|
||||
id: bundles
|
||||
uses: ./.github/actions/get-bundles
|
||||
with:
|
||||
platform: ${{ inputs.platform }}
|
||||
debug-suffix: ${{ matrix.debug-suffix }}
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: |
|
||||
# On macOS we need to install some dependencies for testing
|
||||
brew install make
|
||||
sudo xcode-select --switch /Applications/Xcode_11.7.app/Contents/Developer
|
||||
# This will make GNU make available as 'make' and not only as 'gmake'
|
||||
echo '/usr/local/opt/make/libexec/gnubin' >> $GITHUB_PATH
|
||||
if: runner.os == 'macOS'
|
||||
|
||||
- name: 'Set PATH'
|
||||
id: path
|
||||
run: |
|
||||
# We need a minimal PATH on Windows
|
||||
# Set PATH to "", so just GITHUB_PATH is included
|
||||
if [[ '${{ runner.os }}' == 'Windows' ]]; then
|
||||
echo "value=" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "value=$PATH" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: 'Run tests'
|
||||
id: run-tests
|
||||
run: >
|
||||
make test-prebuilt
|
||||
TEST='${{ matrix.test-suite }}'
|
||||
BOOT_JDK=${{ steps.bootjdk.outputs.path }}
|
||||
JT_HOME=${{ steps.jtreg.outputs.path }}
|
||||
JDK_IMAGE_DIR=${{ steps.bundles.outputs.jdk-path }}
|
||||
SYMBOLS_IMAGE_DIR=${{ steps.bundles.outputs.symbols-path }}
|
||||
TEST_IMAGE_DIR=${{ steps.bundles.outputs.tests-path }}
|
||||
JTREG='JAVA_OPTIONS=-XX:-CreateCoredumpOnCrash;VERBOSE=fail,error,time;KEYWORDS=!headful'
|
||||
&& bash ./.github/scripts/gen-test-summary.sh "$GITHUB_STEP_SUMMARY" "$GITHUB_OUTPUT"
|
||||
env:
|
||||
PATH: ${{ steps.path.outputs.value }}
|
||||
|
||||
# This is a separate step, since if the markdown from a step gets bigger than
|
||||
# 1024 kB it is skipped, but then the short summary above is still generated
|
||||
- name: 'Generate test report'
|
||||
run: bash ./.github/scripts/gen-test-results.sh "$GITHUB_STEP_SUMMARY"
|
||||
if: always()
|
||||
|
||||
- name: 'Package test results'
|
||||
id: package
|
||||
run: |
|
||||
# Package test-results and relevant parts of test-support
|
||||
mkdir results
|
||||
|
||||
if [[ -d build/run-test-prebuilt/test-results ]]; then
|
||||
cd build/run-test-prebuilt/test-results/
|
||||
zip -r -9 "$GITHUB_WORKSPACE/results/test-results.zip" .
|
||||
cd $GITHUB_WORKSPACE
|
||||
else
|
||||
echo '::warning ::Missing test-results directory'
|
||||
fi
|
||||
|
||||
if [[ -d build/run-test-prebuilt/test-support ]]; then
|
||||
cd build/run-test-prebuilt/test-support/
|
||||
zip -r -9 "$GITHUB_WORKSPACE/results/test-support.zip" . -i *.jtr -i */hs_err*.log -i */replay*.log
|
||||
cd $GITHUB_WORKSPACE
|
||||
else
|
||||
echo '::warning ::Missing test-support directory'
|
||||
fi
|
||||
|
||||
artifact_name="results-${{ inputs.platform }}-$(echo ${{ matrix.test-name }} | tr '/ ' '__')"
|
||||
echo "artifact-name=$artifact_name" >> $GITHUB_OUTPUT
|
||||
if: always()
|
||||
|
||||
- name: 'Upload test results'
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: results
|
||||
name: ${{ steps.package.outputs.artifact-name }}
|
||||
if: always()
|
||||
|
||||
# This is the best way I found to abort the job with an error message
|
||||
- name: 'Notify about test failures'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: core.setFailed('${{ steps.run-tests.outputs.error-message }}')
|
||||
if: steps.run-tests.outputs.failure == 'true'
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -18,3 +18,5 @@ NashornProfile.txt
|
||||
/src/utils/LogCompilation/target/
|
||||
/.project/
|
||||
/.settings/
|
||||
*.class
|
||||
.idea/workspace.xml
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
[general]
|
||||
project=jdk
|
||||
jbs=JDK
|
||||
version=21
|
||||
|
||||
[checks]
|
||||
error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists
|
||||
@@ -15,7 +14,7 @@ version=0
|
||||
domain=openjdk.org
|
||||
|
||||
[checks "whitespace"]
|
||||
files=.*\.cpp|.*\.hpp|.*\.c|.*\.h|.*\.java|.*\.cc|.*\.hh|.*\.m|.*\.mm|.*\.md|.*\.gmk|.*\.m4|.*\.ac|Makefile
|
||||
files=.*\.cpp|.*\.hpp|.*\.c|.*\.h|.*\.java|.*\.cc|.*\.hh|.*\.m|.*\.mm|.*\.gmk|.*\.m4|.*\.ac|Makefile
|
||||
ignore-tabs=.*\.gmk|Makefile
|
||||
|
||||
[checks "merge"]
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
OPENJDK ASSEMBLY EXCEPTION
|
||||
|
||||
The OpenJDK source code made available by Oracle America, Inc. (Oracle) at
|
||||
openjdk.org ("OpenJDK Code") is distributed under the terms of the GNU
|
||||
General Public License <https://www.gnu.org/copyleft/gpl.html> version 2
|
||||
openjdk.java.net ("OpenJDK Code") is distributed under the terms of the GNU
|
||||
General Public License <http://www.gnu.org/copyleft/gpl.html> version 2
|
||||
only ("GPL2"), with the following clarification and special exception.
|
||||
|
||||
Linking this OpenJDK Code statically or dynamically with other code
|
||||
@@ -12,7 +12,7 @@ only ("GPL2"), with the following clarification and special exception.
|
||||
|
||||
As a special exception, Oracle gives you permission to link this
|
||||
OpenJDK Code with certain code licensed by Oracle as indicated at
|
||||
https://openjdk.org/legal/exception-modules-2007-05-08.html
|
||||
http://openjdk.java.net/legal/exception-modules-2007-05-08.html
|
||||
("Designated Exception Modules") to produce an executable,
|
||||
regardless of the license terms of the Designated Exception Modules,
|
||||
and to copy and distribute the resulting executable under GPL2,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Contributing to the JDK
|
||||
|
||||
Please see <https://openjdk.org/contribute> for how to contribute.
|
||||
Please see <https://openjdk.java.net/contribute/> for how to contribute.
|
||||
|
||||
180
README.md
180
README.md
@@ -1,12 +1,174 @@
|
||||
# Welcome to the JDK!
|
||||
[](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
|
||||
|
||||
For build instructions please see the
|
||||
[online documentation](https://openjdk.org/groups/build/doc/building.html),
|
||||
or either of these files:
|
||||
# Welcome to JetBrains Runtime!
|
||||
|
||||
- [doc/building.html](doc/building.html) (html version)
|
||||
- [doc/building.md](doc/building.md) (markdown version)
|
||||
JetBrains Runtime is a fork of [OpenJDK](https://github.com/openjdk/jdk) available for Windows, Mac OS X, and Linux.
|
||||
It includes a number enhancements in font rendering, HiDPI support, ligatures, performance improvements, and bugfixes.
|
||||
|
||||
See <https://openjdk.org/> for more information about the OpenJDK
|
||||
Community and the JDK and see <https://bugs.openjdk.org> for JDK issue
|
||||
tracking.
|
||||
> **_NOTE_**: This is a **development** branch that is periodically synhronized with
|
||||
> the [OpenJDK master](https://github.com/openjdk/jdk/tree/master) branch.
|
||||
>
|
||||
> Release builds are based on these branches:
|
||||
> * [master](https://github.com/JetBrains/JetBrainsRuntime/tree/master) (JDK 11)
|
||||
> * [master17](https://github.com/JetBrains/JetBrainsRuntime/tree/master17) (JDK 17)
|
||||
|
||||
|
||||
## Contents
|
||||
- [Welcome to JetBrains Runtime](#jetbrains-runtime)
|
||||
- [Products Built on JetBrains Runtime](#products-built-on-jetbrains-runtime)
|
||||
- [Getting Sources](#getting-sources)
|
||||
- [macOS, Linux](#macos-linux)
|
||||
- [Windows](#sources-windows)
|
||||
- [Configuring the Build Environment](#configuring-the-build-environment)
|
||||
- [Linux (Docker)](#linux-docker)
|
||||
- [Ubuntu Linux](#ubuntu-linux)
|
||||
- [Windows](#build-windows)
|
||||
- [macOS](#macos)
|
||||
- [Developing](#developing)
|
||||
- [Contributing](#contributing)
|
||||
- [Resources](#resources)
|
||||
|
||||
## Products Built on JetBrains Runtime
|
||||
* [Android Studio](https://developer.android.com/studio). The official IDE for Google's Android operating system.
|
||||
* [CLion](https://www.jetbrains.com/clion/). A cross-platform IDE for C and C++ from JetBrains.
|
||||
* [DataGrip](https://www.jetbrains.com/datagrip/). The IDE for Databases and SQL from JetBrains.
|
||||
* [GoLand](https://www.jetbrains.com/go/). The cross-platform Go IDE from JetBrains.
|
||||
* [IntelliJ IDEA](https://www.jetbrains.com/idea/). The IDE for JVM from JetBrains.
|
||||
* [JProfiler](https://www.ej-technologies.com/products/jprofiler/overview.html). The Java profiler.
|
||||
* [PhpStorm](https://www.jetbrains.com/phpstorm/). The PHP IDE from JetBrains.
|
||||
* [PyCharm](https://www.jetbrains.com/pycharm/). The Python IDE from JetBrains.
|
||||
* [Rider](https://www.jetbrains.com/rider/). The cross-platform .NET IDE from JetBrains.
|
||||
* [RubyMine](https://www.jetbrains.com/ruby/). The Ruby and Rails IDE from JetBrains.
|
||||
* [WebStorm](https://www.jetbrains.com/webstorm/). The JavaScript IDE from JetBrains.
|
||||
* [YourKit](https://www.yourkit.com/). Java and .NET profilers.
|
||||
|
||||
## Getting Sources
|
||||
### macOS, Linux
|
||||
```
|
||||
git config --global core.autocrlf input
|
||||
git clone git@github.com:JetBrains/JetBrainsRuntime.git
|
||||
```
|
||||
|
||||
### Windows
|
||||
<a name="sources-windows"></a>
|
||||
```
|
||||
git config --global core.autocrlf false
|
||||
git clone git@github.com:JetBrains/JetBrainsRuntime.git
|
||||
```
|
||||
|
||||
## Configuring the Build Environment
|
||||
Here are quick per-platform instructions for those who can't wait to get started.
|
||||
Please refer to [OpenJDK build docs](https://openjdk.java.net/groups/build/doc/building.html) for in-depth
|
||||
coverage of all the details.
|
||||
|
||||
> **_TIP:_** To get a preliminary report of what's missing, run `./configure` and check its output.
|
||||
> It would usually have a meaningful advice on how to solve the problem.
|
||||
|
||||
### Linux (Docker)
|
||||
Create a container:
|
||||
```
|
||||
$ cd jb/project/docker
|
||||
$ docker build .
|
||||
...
|
||||
Successfully built 942ea9900054
|
||||
```
|
||||
Run these commands in the new container:
|
||||
```
|
||||
$ docker run -v `pwd`../../../../:/JetBrainsRuntime -it 942ea9900054
|
||||
# cd /JetBrainsRuntime
|
||||
# sh ./configure
|
||||
# make images CONF=linux-x86_64-normal-server-release
|
||||
```
|
||||
|
||||
### Ubuntu Linux
|
||||
Install the necessary tools, libraries, and headers with:
|
||||
```
|
||||
$ sudo apt-get install autoconf make build-essential libx11-dev libxext-dev libxrender-dev libxtst-dev \
|
||||
libxt-dev libxrandr-dev libcups2-dev libfontconfig1-dev libasound2-dev
|
||||
```
|
||||
Get Java 17 (for instance, [Azul Zulu Builds of OpenJDK 17](https://www.azul.com/downloads/?version=java-17-ea&package=jdk)).
|
||||
|
||||
Then run the following:
|
||||
```
|
||||
$ cd JetBrainsRuntime
|
||||
$ git checkout jbr-dev
|
||||
$ sh ./configure
|
||||
$ make images
|
||||
```
|
||||
This will build the release configuration under `./build/linux-x86_64-server-release/`.
|
||||
|
||||
### Windows
|
||||
<a name="build-windows"></a>
|
||||
Install the following:
|
||||
* [Cygwin x64](http://www.cygwin.com/).
|
||||
Required packages: `autoconf`, `binutils`, `cpio`, `diffutils`, `file`, `gawk`, `gcc-core`, `make`, `m4`, `unzip`, `zip`.
|
||||
Install those together with Cygwin.
|
||||
* [Visual Studio compiler toolset](https://visualstudio.microsoft.com/downloads/).
|
||||
Install with the desktop development kit, which includes Windows SDK and compilers.
|
||||
Visual Studio 2019 is supported by default.
|
||||
* Java 17 (for instance, [Azul Zulu Builds of OpenJDK 17](https://www.azul.com/downloads/?version=java-17-ea&os=windows&architecture=x86-64-bit&package=jdk).
|
||||
If you have problems while configuring, read [Java tips on Cygwin](http://horstmann.com/articles/cygwin-tips.html).
|
||||
|
||||
From the command line:
|
||||
```
|
||||
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
|
||||
"c:\Program_Files\cygwin64\bin\mintty.exe" /bin/bash -l
|
||||
```
|
||||
The first command sets up environment variables, the second starts a Cygwin shell with the proper environment.
|
||||
|
||||
In the Cygwin shell:
|
||||
```
|
||||
$ cd JetBrainsRuntime
|
||||
$ git checkout jbr-dev
|
||||
$ bash configure --with-toolchain-version=2019
|
||||
$ make images
|
||||
```
|
||||
This will build the release configuration under `./build/windows-x86_64-server-release/`.
|
||||
|
||||
### macOS
|
||||
Install the following:
|
||||
* Xcode command line developer tools and `autoconf` via [Homebrew](https://brew.sh/).
|
||||
* Java 17 (for instance, [Azul Zulu Builds of OpenJDK 17](https://www.azul.com/downloads/?version=java-17-ea&package=jdk)).
|
||||
|
||||
From the command line:
|
||||
```
|
||||
$ cd JetBrainsRuntime
|
||||
$ git checkout jbr-dev
|
||||
$ sh ./configure
|
||||
$ make images
|
||||
```
|
||||
This will build the release configuration under `./build/macosx-x86_64-server-release/`.
|
||||
|
||||
## Developing
|
||||
You can use [CLion](https://www.jetbrains.com/clion/) to develop native parts of the JetBrains Runtime and
|
||||
[IntelliJ IDEA](https://www.jetbrains.com/idea/) for the parts written in Java.
|
||||
Both require projects to be created.
|
||||
|
||||
### CLion
|
||||
Run
|
||||
```
|
||||
$ make compile-commands
|
||||
```
|
||||
in the git root and open the resulting `build/.../compile_commands.json` file as a project.
|
||||
Then use `Tools | Compilation Database | Change Project Root` to point to git root of this repository.
|
||||
|
||||
See also this detailed step-by-step tutorial for all platforms:
|
||||
[How to develop OpenJDK with CLion](https://blog.jetbrains.com/clion/2020/03/openjdk-with-clion/).
|
||||
|
||||
### IDEA
|
||||
Run
|
||||
```
|
||||
$ sh ./bin/idea.sh
|
||||
```
|
||||
in the git root to generate project files (add `--help` for options). If you have multiple
|
||||
configurations (for example, `release` and `fastdebug`), supply the `--conf <conf_name>` argument.
|
||||
Then open the git root directory as a project in IDEA.
|
||||
|
||||
## Contributing
|
||||
We are happy to receive your pull requests!
|
||||
Before you submit one, please sign our [Contributor License Agreement (CLA)](https://www.jetbrains.com/agreements/cla/).
|
||||
|
||||
## Resources
|
||||
* [JetBrains Runtime on github](https://github.com/JetBrains/JetBrainsRuntime).
|
||||
* [OpenJDK build instructions](https://openjdk.java.net/groups/build/doc/building.html).
|
||||
* [OpenJDK test instructions](https://htmlpreview.github.io/?https://raw.githubusercontent.com/openjdk/jdk/master/doc/building.html#running-tests).
|
||||
|
||||
305
bin/idea.sh
305
bin/idea.sh
@@ -25,7 +25,26 @@
|
||||
# Shell script for generating an IDEA project from a given list of modules
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [-h|--help] [-v|--verbose] [-o|--output <path>] [-c|--conf <conf_name>] [modules]+"
|
||||
echo "Usage: $0 [-h|--help] [-q|--quiet] [-a|--absolute-paths] [-r|--root <path>] [-o|--output <path>] [-c|--conf <conf_name>] [modules...]"
|
||||
echo " -h | --help"
|
||||
echo " -q | --quiet
|
||||
No stdout output"
|
||||
echo " -a | --absolute-paths
|
||||
Use absolute paths to this jdk, so that generated .idea
|
||||
project files can be moved independently of jdk sources"
|
||||
echo " -r | --root <path>
|
||||
Project content root
|
||||
Default: $TOPLEVEL_DIR"
|
||||
echo " -o | --output <path>
|
||||
Where .idea directory with project files will be generated
|
||||
(e.g. using '-o .' will place project files in './.idea')
|
||||
Default: same as --root"
|
||||
echo " -c | --conf <conf_name>
|
||||
make configuration (release, slowdebug etc)"
|
||||
echo " [modules...]
|
||||
Generate project modules for specific java modules
|
||||
(e.g. 'java.base java.desktop')
|
||||
Default: all existing modules (java.* and jdk.*)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -33,10 +52,13 @@ SCRIPT_DIR=`dirname $0`
|
||||
#assume TOP is the dir from which the script has been called
|
||||
TOP=`pwd`
|
||||
cd $SCRIPT_DIR; SCRIPT_DIR=`pwd`
|
||||
if [ "x$TOPLEVEL_DIR" = "x" ] ; then
|
||||
cd .. ; TOPLEVEL_DIR=`pwd`
|
||||
fi
|
||||
cd $TOP;
|
||||
|
||||
IDEA_OUTPUT=$TOP/.idea
|
||||
VERBOSE="false"
|
||||
VERBOSE=true
|
||||
ABSOLUTE_PATHS=false
|
||||
CONF_ARG=
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
@@ -45,14 +67,24 @@ do
|
||||
usage
|
||||
;;
|
||||
|
||||
-v | --vebose )
|
||||
VERBOSE="true"
|
||||
-q | --quiet )
|
||||
VERBOSE=false
|
||||
;;
|
||||
|
||||
-a | --absolute-paths )
|
||||
ABSOLUTE_PATHS=true
|
||||
;;
|
||||
|
||||
-r | --root )
|
||||
TOPLEVEL_DIR="$2"
|
||||
shift
|
||||
;;
|
||||
|
||||
-o | --output )
|
||||
IDEA_OUTPUT=$2/.idea
|
||||
IDEA_OUTPUT="$2/.idea"
|
||||
shift
|
||||
;;
|
||||
|
||||
-c | --conf )
|
||||
CONF_ARG="CONF_NAME=$2"
|
||||
shift
|
||||
@@ -69,23 +101,21 @@ do
|
||||
shift
|
||||
done
|
||||
|
||||
if [ -e $IDEA_OUTPUT ] ; then
|
||||
rm -r $IDEA_OUTPUT
|
||||
if [ "x$IDEA_OUTPUT" = "x" ] ; then
|
||||
IDEA_OUTPUT="$TOPLEVEL_DIR/.idea"
|
||||
fi
|
||||
|
||||
mkdir -p $IDEA_OUTPUT || exit 1
|
||||
cd $IDEA_OUTPUT; IDEA_OUTPUT=`pwd`
|
||||
cd "$TOP" ; cd $TOPLEVEL_DIR; TOPLEVEL_DIR=`pwd`
|
||||
cd "$TOP" ; cd $IDEA_OUTPUT; IDEA_OUTPUT=`pwd`
|
||||
cd ..; IDEA_OUTPUT_PARENT=`pwd`
|
||||
cd "$SCRIPT_DIR/.." ; OPENJDK_DIR=`pwd`
|
||||
|
||||
if [ "x$TOPLEVEL_DIR" = "x" ] ; then
|
||||
cd $SCRIPT_DIR/..
|
||||
TOPLEVEL_DIR=`pwd`
|
||||
cd $IDEA_OUTPUT
|
||||
fi
|
||||
|
||||
MAKE_DIR="$SCRIPT_DIR/../make"
|
||||
IDEA_MAKE="$MAKE_DIR/ide/idea/jdk"
|
||||
IDEA_MAKE="$OPENJDK_DIR/make/ide/idea/jdk"
|
||||
IDEA_TEMPLATE="$IDEA_MAKE/template"
|
||||
|
||||
cp -r "$IDEA_TEMPLATE"/* "$IDEA_OUTPUT"
|
||||
cp -rn "$TOPLEVEL_DIR/jb/project/idea-project-files"/* "$IDEA_OUTPUT"
|
||||
cp -rn "$IDEA_TEMPLATE"/* "$IDEA_OUTPUT"
|
||||
|
||||
#override template
|
||||
if [ -d "$TEMPLATES_OVERRIDE" ] ; then
|
||||
@@ -94,31 +124,31 @@ if [ -d "$TEMPLATES_OVERRIDE" ] ; then
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$VERBOSE" = "true" ] ; then
|
||||
echo "output dir: $IDEA_OUTPUT"
|
||||
echo "idea template dir: $IDEA_TEMPLATE"
|
||||
if [ "$VERBOSE" = true ] ; then
|
||||
echo "Will generate IDEA project files in \"$IDEA_OUTPUT\" for project \"$TOPLEVEL_DIR\""
|
||||
fi
|
||||
|
||||
cd $TOP ; make -f "$IDEA_MAKE/idea.gmk" -I $MAKE_DIR/.. idea MAKEOVERRIDES= OUT=$IDEA_OUTPUT/env.cfg MODULES="$*" $CONF_ARG || exit 1
|
||||
cd $TOP ; make -f "$IDEA_MAKE/idea.gmk" -I "$OPENJDK_DIR" idea TOPLEVEL_DIR="$TOPLEVEL_DIR" \
|
||||
MAKEOVERRIDES= IDEA_OUTPUT_PARENT="$IDEA_OUTPUT_PARENT" OUT="$IDEA_OUTPUT/env.cfg" MODULES="$*" $CONF_ARG || exit 1
|
||||
cd $SCRIPT_DIR
|
||||
|
||||
. $IDEA_OUTPUT/env.cfg
|
||||
|
||||
# Expect MODULE_ROOTS, MODULE_NAMES, BOOT_JDK & SPEC to be set
|
||||
if [ "x$MODULE_ROOTS" = "x" ] ; then
|
||||
echo "FATAL: MODULE_ROOTS is empty" >&2; exit 1
|
||||
# Expect MODULES, MODULE_NAMES, RELATIVE_PROJECT_DIR, RELATIVE_BUILD_DIR to be set
|
||||
if [ "xMODULES" = "x" ] ; then
|
||||
echo "FATAL: MODULES is empty" >&2; exit 1
|
||||
fi
|
||||
|
||||
if [ "x$MODULE_NAMES" = "x" ] ; then
|
||||
echo "FATAL: MODULE_NAMES is empty" >&2; exit 1
|
||||
fi
|
||||
|
||||
if [ "x$BOOT_JDK" = "x" ] ; then
|
||||
echo "FATAL: BOOT_JDK is empty" >&2; exit 1
|
||||
if [ "x$RELATIVE_PROJECT_DIR" = "x" ] ; then
|
||||
echo "FATAL: RELATIVE_PROJECT_DIR is empty" >&2; exit 1
|
||||
fi
|
||||
|
||||
if [ "x$SPEC" = "x" ] ; then
|
||||
echo "FATAL: SPEC is empty" >&2; exit 1
|
||||
if [ "x$RELATIVE_BUILD_DIR" = "x" ] ; then
|
||||
echo "FATAL: RELATIVE_BUILD_DIR is empty" >&2; exit 1
|
||||
fi
|
||||
|
||||
if [ -d "$TOPLEVEL_DIR/.hg" ] ; then
|
||||
@@ -129,6 +159,43 @@ if [ -d "$TOPLEVEL_DIR/.git" ] ; then
|
||||
VCS_TYPE="Git"
|
||||
fi
|
||||
|
||||
if [ "$ABSOLUTE_PATHS" = true ] ; then
|
||||
if [ "x$PATHTOOL" != "x" ]; then
|
||||
PROJECT_DIR="`$PATHTOOL -am $OPENJDK_DIR`"
|
||||
TOPLEVEL_PROJECT_DIR="`$PATHTOOL -am $TOPLEVEL_DIR`"
|
||||
else
|
||||
PROJECT_DIR="$OPENJDK_DIR"
|
||||
TOPLEVEL_PROJECT_DIR="$TOPLEVEL_DIR"
|
||||
fi
|
||||
MODULE_DIR="$PROJECT_DIR"
|
||||
TOPLEVEL_MODULE_DIR="$TOPLEVEL_PROJECT_DIR"
|
||||
cd "$IDEA_OUTPUT_PARENT" && cd "$RELATIVE_BUILD_DIR" && BUILD_DIR="`pwd`"
|
||||
CLION_SCRIPT_TOPDIR="$OPENJDK_DIR"
|
||||
CLION_PROJECT_DIR="$PROJECT_DIR"
|
||||
else
|
||||
if [ "$RELATIVE_PROJECT_DIR" = "." ] ; then
|
||||
PROJECT_DIR=""
|
||||
else
|
||||
PROJECT_DIR="/$RELATIVE_PROJECT_DIR"
|
||||
fi
|
||||
if [ "$RELATIVE_TOPLEVEL_PROJECT_DIR" = "." ] ; then
|
||||
TOPLEVEL_PROJECT_DIR=""
|
||||
else
|
||||
TOPLEVEL_PROJECT_DIR="/$RELATIVE_TOPLEVEL_PROJECT_DIR"
|
||||
fi
|
||||
MODULE_DIR="\$MODULE_DIR\$$PROJECT_DIR"
|
||||
PROJECT_DIR="\$PROJECT_DIR\$$PROJECT_DIR"
|
||||
TOPLEVEL_MODULE_DIR="\$MODULE_DIR\$$TOPLEVEL_PROJECT_DIR"
|
||||
TOPLEVEL_PROJECT_DIR="\$PROJECT_DIR\$$TOPLEVEL_PROJECT_DIR"
|
||||
BUILD_DIR="\$PROJECT_DIR\$/$RELATIVE_BUILD_DIR"
|
||||
CLION_SCRIPT_TOPDIR="$CLION_RELATIVE_PROJECT_DIR"
|
||||
CLION_PROJECT_DIR="\$PROJECT_DIR\$/$CLION_SCRIPT_TOPDIR"
|
||||
fi
|
||||
if [ "$VERBOSE" = true ] ; then
|
||||
echo "Project root: $PROJECT_DIR"
|
||||
echo "Generating IDEA project files..."
|
||||
fi
|
||||
|
||||
### Replace template variables
|
||||
|
||||
NUM_REPLACEMENTS=0
|
||||
@@ -152,126 +219,106 @@ add_replacement() {
|
||||
eval TO$NUM_REPLACEMENTS='$2'
|
||||
}
|
||||
|
||||
add_replacement "###PATHTOOL###" "$PATHTOOL"
|
||||
add_replacement "###CLION_SCRIPT_TOPDIR###" "$CLION_SCRIPT_TOPDIR"
|
||||
add_replacement "###CLION_PROJECT_DIR###" "$CLION_PROJECT_DIR"
|
||||
add_replacement "###PROJECT_DIR###" "$PROJECT_DIR"
|
||||
add_replacement "###MODULE_DIR###" "$MODULE_DIR"
|
||||
add_replacement "###TOPLEVEL_PROJECT_DIR###" "$TOPLEVEL_PROJECT_DIR"
|
||||
add_replacement "###TOPLEVEL_MODULE_DIR###" "$TOPLEVEL_MODULE_DIR"
|
||||
add_replacement "###MODULE_NAMES###" "$MODULE_NAMES"
|
||||
add_replacement "###VCS_TYPE###" "$VCS_TYPE"
|
||||
SPEC_DIR=`dirname $SPEC`
|
||||
if [ "x$CYGPATH" != "x" ]; then
|
||||
add_replacement "###BUILD_DIR###" "`$CYGPATH -am $SPEC_DIR`"
|
||||
add_replacement "###IMAGES_DIR###" "`$CYGPATH -am $SPEC_DIR`/images/jdk"
|
||||
add_replacement "###ROOT_DIR###" "`$CYGPATH -am $TOPLEVEL_DIR`"
|
||||
add_replacement "###IDEA_DIR###" "`$CYGPATH -am $IDEA_OUTPUT`"
|
||||
add_replacement "###BUILD_DIR###" "$BUILD_DIR"
|
||||
add_replacement "###RELATIVE_BUILD_DIR###" "$RELATIVE_BUILD_DIR"
|
||||
if [ "x$PATHTOOL" != "x" ]; then
|
||||
add_replacement "###BASH_RUNNER_PREFIX###" "\$PROJECT_DIR\$/.idea/bash.bat"
|
||||
else
|
||||
add_replacement "###BASH_RUNNER_PREFIX###" ""
|
||||
fi
|
||||
if [ "x$PATHTOOL" != "x" ]; then
|
||||
if [ "x$JT_HOME" = "x" ]; then
|
||||
add_replacement "###JTREG_HOME###" ""
|
||||
else
|
||||
add_replacement "###JTREG_HOME###" "`$CYGPATH -am $JT_HOME`"
|
||||
fi
|
||||
elif [ "x$WSL_DISTRO_NAME" != "x" ]; then
|
||||
add_replacement "###BUILD_DIR###" "`wslpath -am $SPEC_DIR`"
|
||||
add_replacement "###IMAGES_DIR###" "`wslpath -am $SPEC_DIR`/images/jdk"
|
||||
add_replacement "###ROOT_DIR###" "`wslpath -am $TOPLEVEL_DIR`"
|
||||
add_replacement "###IDEA_DIR###" "`wslpath -am $IDEA_OUTPUT`"
|
||||
if [ "x$JT_HOME" = "x" ]; then
|
||||
add_replacement "###JTREG_HOME###" ""
|
||||
else
|
||||
add_replacement "###JTREG_HOME###" "`wslpath -am $JT_HOME`"
|
||||
add_replacement "###JTREG_HOME###" "`$PATHTOOL -am $JT_HOME`"
|
||||
fi
|
||||
else
|
||||
add_replacement "###BUILD_DIR###" "$SPEC_DIR"
|
||||
add_replacement "###JTREG_HOME###" "$JT_HOME"
|
||||
add_replacement "###IMAGES_DIR###" "$SPEC_DIR/images/jdk"
|
||||
add_replacement "###ROOT_DIR###" "$TOPLEVEL_DIR"
|
||||
add_replacement "###IDEA_DIR###" "$IDEA_OUTPUT"
|
||||
fi
|
||||
|
||||
SOURCE_PREFIX="<sourceFolder url=\"file://"
|
||||
SOURCE_POSTFIX="\" isTestSource=\"false\" />"
|
||||
|
||||
for root in $MODULE_ROOTS; do
|
||||
if [ "x$CYGPATH" != "x" ]; then
|
||||
root=`$CYGPATH -am $root`
|
||||
elif [ "x$WSL_DISTRO_NAME" != "x" ]; then
|
||||
root=`wslpath -am $root`
|
||||
fi
|
||||
|
||||
VM_CI="jdk.internal.vm.ci/share/classes"
|
||||
VM_COMPILER="src/jdk.internal.vm.compiler/share/classes"
|
||||
if test "${root#*$VM_CI}" != "$root" || test "${root#*$VM_COMPILER}" != "$root"; then
|
||||
for subdir in "$root"/*; do
|
||||
if [ -d "$subdir" ]; then
|
||||
SOURCES=$SOURCES" $SOURCE_PREFIX""$subdir"/src"$SOURCE_POSTFIX"
|
||||
fi
|
||||
done
|
||||
else
|
||||
SOURCES=$SOURCES" $SOURCE_PREFIX""$root""$SOURCE_POSTFIX"
|
||||
fi
|
||||
MODULE_IMLS=""
|
||||
TEST_MODULE_DEPENDENCIES=""
|
||||
for module in $MODULE_NAMES; do
|
||||
MODULE_IMLS="$MODULE_IMLS<module fileurl=\"file://\$PROJECT_DIR$/.idea/$module.iml\" filepath=\"\$PROJECT_DIR$/.idea/$module.iml\" /> "
|
||||
TEST_MODULE_DEPENDENCIES="$TEST_MODULE_DEPENDENCIES<orderEntry type=\"module\" module-name=\"$module\" scope=\"TEST\" /> "
|
||||
done
|
||||
|
||||
add_replacement "###SOURCE_ROOTS###" "$SOURCES"
|
||||
add_replacement "###MODULE_IMLS###" "$MODULE_IMLS"
|
||||
add_replacement "###TEST_MODULE_DEPENDENCIES###" "$TEST_MODULE_DEPENDENCIES"
|
||||
|
||||
replace_template_dir "$IDEA_OUTPUT"
|
||||
|
||||
### Compile the custom Logger
|
||||
### Generate module project files
|
||||
|
||||
CLASSES=$IDEA_OUTPUT/classes
|
||||
if [ "$VERBOSE" = true ] ; then
|
||||
echo "Generating project modules:"
|
||||
fi
|
||||
(
|
||||
DEFAULT_IFS="$IFS"
|
||||
IFS='#'
|
||||
for value in $MODULES; do
|
||||
(
|
||||
eval "$value"
|
||||
if [ "$VERBOSE" = true ] ; then
|
||||
echo " $module"
|
||||
fi
|
||||
MAIN_SOURCE_DIRS=""
|
||||
CONTENT_ROOTS=""
|
||||
IFS=' '
|
||||
for dir in $moduleSrcDirs; do
|
||||
case $dir in
|
||||
"src/"*) MAIN_SOURCE_DIRS="$MAIN_SOURCE_DIRS <sourceFolder url=\"file://$MODULE_DIR/$dir\" isTestSource=\"false\" />" ;;
|
||||
*"/support/gensrc/$module") ;; # Exclude generated sources to avoid module-info conflicts, see https://youtrack.jetbrains.com/issue/IDEA-185108
|
||||
*) CONTENT_ROOTS="$CONTENT_ROOTS <content url=\"file://$MODULE_DIR/$dir\">\
|
||||
<sourceFolder url=\"file://$MODULE_DIR/$dir\" isTestSource=\"false\" generated=\"true\" /></content>" ;;
|
||||
esac
|
||||
done
|
||||
if [ "x$MAIN_SOURCE_DIRS" != "x" ] ; then
|
||||
CONTENT_ROOTS="<content url=\"file://$MODULE_DIR/src/$module\">$MAIN_SOURCE_DIRS</content>$CONTENT_ROOTS"
|
||||
fi
|
||||
add_replacement "###MODULE_CONTENT_ROOTS###" "$CONTENT_ROOTS"
|
||||
DEPENDENCIES=""
|
||||
for dep in $moduleDependencies; do
|
||||
case $MODULE_NAMES in # Exclude skipped modules from dependencies
|
||||
*"$dep"*) DEPENDENCIES="$DEPENDENCIES<orderEntry type=\"module\" module-name=\"$dep\" /> "
|
||||
esac
|
||||
done
|
||||
add_replacement "###DEPENDENCIES###" "$DEPENDENCIES"
|
||||
cp "$IDEA_OUTPUT/module.iml" "$IDEA_OUTPUT/$module.iml"
|
||||
IFS="$DEFAULT_IFS"
|
||||
replace_template_file "$IDEA_OUTPUT/$module.iml"
|
||||
)
|
||||
done
|
||||
)
|
||||
rm "$IDEA_OUTPUT/module.iml"
|
||||
|
||||
if [ "x$ANT_HOME" = "x" ] ; then
|
||||
# try some common locations
|
||||
if [ -f "/usr/share/ant/lib/ant.jar" ] ; then
|
||||
ANT_HOME="/usr/share/ant"
|
||||
### Create shell script runner for Windows
|
||||
|
||||
if [ "x$PATHTOOL" != "x" ]; then
|
||||
echo "@echo off" > "$IDEA_OUTPUT/bash.bat"
|
||||
if [ "x$WSL_DISTRO_NAME" != "x" ] ; then
|
||||
echo "wsl -d $WSL_DISTRO_NAME --cd \"%cd%\" -e %*" >> "$IDEA_OUTPUT/bash.bat"
|
||||
else
|
||||
try_ant=$(ls /opt/homebrew/Cellar/ant/*/libexec/lib/ant.jar 2> /dev/null | sort -r | head -n 1)
|
||||
if [ "x$try_ant" != "x" ] ; then
|
||||
ANT_HOME=$(cd $(dirname $try_ant)/.. && pwd)
|
||||
else
|
||||
try_ant=$(ls /usr/local/Cellar/ant/*/libexec/lib/ant.jar 2> /dev/null | sort -r | head -n 1)
|
||||
if [ "x$try_ant" != "x" ] ; then
|
||||
ANT_HOME=$(cd $(dirname $try_ant)/.. && pwd)
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ ! -f "$ANT_HOME/lib/ant.jar" ] ; then
|
||||
echo "FATAL: ANT_HOME is incorrect. Try removing it and use autodetection, or fix the value" >&2; exit 1
|
||||
echo "$WINENV_ROOT\bin\bash.exe -l -c \"cd %CD:\=/%/ && %*\"" >> "$IDEA_OUTPUT/bash.bat"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "x$ANT_HOME" = "x" ] ; then
|
||||
echo "FATAL: cannot find ant. Try setting ANT_HOME." >&2; exit 1
|
||||
fi
|
||||
CP=$ANT_HOME/lib/ant.jar
|
||||
rm -rf $CLASSES; mkdir $CLASSES
|
||||
|
||||
# If we have a Windows boot JDK, we need a .exe suffix
|
||||
if [ -e "$BOOT_JDK/bin/java.exe" ] ; then
|
||||
JAVAC=javac.exe
|
||||
else
|
||||
JAVAC=javac
|
||||
fi
|
||||
|
||||
# If we are on WSL, the boot JDK might be either Windows or Linux,
|
||||
# and we need to use realpath instead of CYGPATH to make javac work on both.
|
||||
# We need to handle this case first since CYGPATH might be set on WSL.
|
||||
if [ "x$WSL_DISTRO_NAME" != "x" ]; then
|
||||
JAVAC_SOURCE_FILE=`realpath --relative-to=./ $IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java`
|
||||
JAVAC_SOURCE_PATH=`realpath --relative-to=./ $IDEA_OUTPUT/src`
|
||||
JAVAC_CLASSES=`realpath --relative-to=./ $CLASSES`
|
||||
ANT_TEMP=`mktemp -d -p ./`
|
||||
cp $ANT_HOME/lib/ant.jar $ANT_TEMP/ant.jar
|
||||
JAVAC_CP=$ANT_TEMP/ant.jar
|
||||
elif [ "x$CYGPATH" != "x" ] ; then ## CYGPATH may be set in env.cfg
|
||||
JAVAC_SOURCE_FILE=`$CYGPATH -am $IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java`
|
||||
JAVAC_SOURCE_PATH=`$CYGPATH -am $IDEA_OUTPUT/src`
|
||||
JAVAC_CLASSES=`$CYGPATH -am $CLASSES`
|
||||
JAVAC_CP=`$CYGPATH -am $CP`
|
||||
else
|
||||
JAVAC_SOURCE_FILE=$IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java
|
||||
JAVAC_SOURCE_PATH=$IDEA_OUTPUT/src
|
||||
JAVAC_CLASSES=$CLASSES
|
||||
JAVAC_CP=$CP
|
||||
fi
|
||||
|
||||
$BOOT_JDK/bin/$JAVAC -d $JAVAC_CLASSES -sourcepath $JAVAC_SOURCE_PATH -cp $JAVAC_CP $JAVAC_SOURCE_FILE
|
||||
|
||||
if [ "x$WSL_DISTRO_NAME" != "x" ]; then
|
||||
rm -rf $ANT_TEMP
|
||||
if [ "$VERBOSE" = true ] ; then
|
||||
IDEA_PROJECT_DIR="`dirname $IDEA_OUTPUT`"
|
||||
if [ "x$PATHTOOL" != "x" ]; then
|
||||
IDEA_PROJECT_DIR="`$PATHTOOL -am $IDEA_PROJECT_DIR`"
|
||||
fi
|
||||
echo "
|
||||
Now you can open \"$IDEA_PROJECT_DIR\" as IDEA project
|
||||
You can also run 'bash \"$IDEA_OUTPUT/jdk-clion/update-project.sh\"' to generate Clion project"
|
||||
fi
|
||||
45
bin/jib.sh
45
bin/jib.sh
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -128,15 +128,6 @@ install_jib() {
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# Want to check the filetype using file, to see if we got served a HTML error page.
|
||||
# This is sensitive to the filename containing a specific string, but good enough.
|
||||
file ${installed_jib_script}.gz | grep "gzip compressed data" > /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Warning: ${installed_jib_script}.gz is not a gzip file."
|
||||
echo "If you are behind a proxy you may need to configure exceptions using no_proxy."
|
||||
echo "The download URL was: ${jib_url}"
|
||||
exit 1
|
||||
fi
|
||||
echo "Extracting JIB bootstrap script"
|
||||
rm -f "${installed_jib_script}"
|
||||
gunzip "${installed_jib_script}.gz"
|
||||
@@ -144,28 +135,6 @@ install_jib() {
|
||||
echo "${data_string}" > "${install_data}"
|
||||
}
|
||||
|
||||
# Returns a shell-escaped version of the argument given.
|
||||
shell_quote() {
|
||||
if [[ -n "$1" ]]; then
|
||||
# Uses only shell-safe characters? No quoting needed.
|
||||
# '=' is a zsh meta-character, but only in word-initial position.
|
||||
if echo "$1" | grep '^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\.:,%/+=_-]\{1,\}$' > /dev/null \
|
||||
&& ! echo "$1" | grep '^=' > /dev/null; then
|
||||
quoted="$1"
|
||||
else
|
||||
if echo "$1" | grep "[\'!]" > /dev/null; then
|
||||
# csh does history expansion within single quotes, but not
|
||||
# when backslash-escaped!
|
||||
local quoted_quote="'\\''" quoted_exclam="'\\!'"
|
||||
word="${1//\'/${quoted_quote}}"
|
||||
word="${1//\!/${quoted_exclam}}"
|
||||
fi
|
||||
quoted="'$1'"
|
||||
fi
|
||||
echo "$quoted"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main body starts here
|
||||
|
||||
setup_url
|
||||
@@ -182,16 +151,4 @@ if [ -z "${JIB_SRC_DIR}" ]; then
|
||||
export JIB_SRC_DIR="${mydir}/../"
|
||||
fi
|
||||
|
||||
|
||||
# Save the original command line
|
||||
conf_quoted_arguments=()
|
||||
for conf_option; do
|
||||
conf_quoted_arguments=("${conf_quoted_arguments[@]}" "$(shell_quote "$conf_option")")
|
||||
done
|
||||
export REAL_CONFIGURE_COMMAND_LINE="${conf_quoted_arguments[@]}"
|
||||
|
||||
myfulldir="$(cd "${mydir}" > /dev/null && pwd)"
|
||||
export REAL_CONFIGURE_COMMAND_EXEC_FULL="$BASH $myfulldir/$myname"
|
||||
export REAL_CONFIGURE_COMMAND_EXEC_SHORT="$myname"
|
||||
|
||||
${installed_jib_script} "$@"
|
||||
|
||||
45
bin/print-config.js
Normal file
45
bin/print-config.js
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This little utility can be used to expand the jib-profiles configuration
|
||||
* files into plain json.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* jjs -scripting print-config.js -- [<jib-profiles.js>]
|
||||
*
|
||||
*/
|
||||
|
||||
var file = $ARG[0];
|
||||
if (file == null) {
|
||||
file = new java.io.File(__DIR__, "../conf/jib-profiles.js").getCanonicalPath();
|
||||
}
|
||||
load(file);
|
||||
var input = {};
|
||||
input.get = function(dependencyName, attribute) {
|
||||
return "\${" + dependencyName + "." + attribute + "}";
|
||||
};
|
||||
print(JSON.stringify(getJibProfiles(input), null, 2));
|
||||
2251
doc/building.html
2251
doc/building.html
File diff suppressed because it is too large
Load Diff
267
doc/building.md
267
doc/building.md
@@ -7,7 +7,7 @@ the time. They assume that you have installed Git (and Cygwin if running
|
||||
on Windows) and cloned the top-level JDK repository that you want to build.
|
||||
|
||||
1. [Get the complete source code](#getting-the-source-code): \
|
||||
`git clone https://git.openjdk.org/jdk/`
|
||||
`git clone https://git.openjdk.java.net/jdk/`
|
||||
|
||||
2. [Run configure](#running-configure): \
|
||||
`bash configure`
|
||||
@@ -40,14 +40,14 @@ reasonably powerful hardware.
|
||||
|
||||
If you just want to use the JDK and not build it yourself, this document is not
|
||||
for you. See for instance [OpenJDK installation](
|
||||
http://openjdk.org/install) for some methods of installing a prebuilt
|
||||
http://openjdk.java.net/install) for some methods of installing a prebuilt
|
||||
JDK.
|
||||
|
||||
## Getting the Source Code
|
||||
|
||||
Make sure you are getting the correct version. As of JDK 10, the source is no
|
||||
longer split into separate repositories so you only need to clone one single
|
||||
repository. At the [OpenJDK Git site](https://git.openjdk.org/) you
|
||||
repository. At the [OpenJDK Git site](https://git.openjdk.java.net/) you
|
||||
can see a list of all available repositories. If you want to build an older version,
|
||||
e.g. JDK 11, it is recommended that you get the `jdk11u` repo, which contains
|
||||
incremental updates, instead of the `jdk11` repo, which was frozen at JDK 11 GA.
|
||||
@@ -96,7 +96,7 @@ on where and how to check out the source code.
|
||||
Cygwin paths (which are used throughout the JDK build system).
|
||||
However, it does not currently work well with the Skara CLI tooling.
|
||||
Please see the [Skara wiki on Git clients](
|
||||
https://wiki.openjdk.org/display/SKARA/Skara#Skara-Git) for
|
||||
https://wiki.openjdk.java.net/display/SKARA/Skara#Skara-Git) for
|
||||
up-to-date information about the Skara git client support.
|
||||
|
||||
* The [Git for Windows](https://gitforwindows.org) client has issues
|
||||
@@ -135,14 +135,6 @@ space is required.
|
||||
If you do not have access to sufficiently powerful hardware, it is also
|
||||
possible to use [cross-compiling](#cross-compiling).
|
||||
|
||||
#### Branch Protection
|
||||
|
||||
In order to use Branch Protection features in the VM, `--enable-branch-protection`
|
||||
must be used. This option requires C++ compiler support (GCC 9.1.0+ or Clang
|
||||
10+). The resulting build can be run on both machines with and without support
|
||||
for branch protection in hardware. Branch Protection is only supported for
|
||||
Linux targets.
|
||||
|
||||
### Building on 32-bit arm
|
||||
|
||||
This is not recommended. Instead, see the section on [Cross-compiling](
|
||||
@@ -173,7 +165,7 @@ used at Oracle, where header files and external libraries from an older version
|
||||
are used when building on a more modern version of the OS.
|
||||
|
||||
The Build Group has a wiki page with [Supported Build Platforms](
|
||||
https://wiki.openjdk.org/display/Build/Supported+Build+Platforms). From
|
||||
https://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms). From
|
||||
time to time, this is updated by contributors to list successes or failures of
|
||||
building on different platforms.
|
||||
|
||||
@@ -187,10 +179,10 @@ On Windows, it is important that you pay attention to the instructions in the
|
||||
|
||||
Windows is the only non-POSIX OS supported by the JDK, and as such, requires
|
||||
some extra care. A POSIX support layer is required to build on Windows.
|
||||
Currently, the only supported such layers are Cygwin, Windows Subsystem for
|
||||
Linux (WSL), and MSYS2. (MSYS is no longer supported due to an outdated bash;
|
||||
While OpenJDK can be built with MSYS2, support for it is still experimental, so
|
||||
build failures and unusual errors are not uncommon.)
|
||||
Currently, the only supported such layers are Cygwin and Windows Subsystem for
|
||||
Linux (WSL). (Msys is no longer supported due to a too old bash; msys2 would
|
||||
likely be possible to support in a future version but that would require effort
|
||||
to implement.)
|
||||
|
||||
Internally in the build system, all paths are represented as Unix-style paths,
|
||||
e.g. `/cygdrive/c/git/jdk/Makefile` rather than `C:\git\jdk\Makefile`. This
|
||||
@@ -244,8 +236,8 @@ It's possible to build both Windows and Linux binaries from WSL. To build
|
||||
Windows binaries, you must use a Windows boot JDK (located in a
|
||||
Windows-accessible directory). To build Linux binaries, you must use a Linux
|
||||
boot JDK. The default behavior is to build for Windows. To build for Linux, pass
|
||||
`--build=x86_64-unknown-linux-gnu --openjdk-target=x86_64-unknown-linux-gnu`
|
||||
to `configure`.
|
||||
`--build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu` to
|
||||
`configure`.
|
||||
|
||||
If building Windows binaries, the source code must be located in a Windows-
|
||||
accessible directory. This is because Windows executables (such as Visual Studio
|
||||
@@ -303,7 +295,7 @@ sudo apk add build-base bash grep zip
|
||||
### AIX
|
||||
|
||||
Please consult the AIX section of the [Supported Build Platforms](
|
||||
https://wiki.openjdk.org/display/Build/Supported+Build+Platforms) OpenJDK
|
||||
https://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms) OpenJDK
|
||||
Build Wiki page for details about which versions of AIX are supported.
|
||||
|
||||
## Native Compiler (Toolchain) Requirements
|
||||
@@ -311,17 +303,14 @@ Build Wiki page for details about which versions of AIX are supported.
|
||||
Large portions of the JDK consists of native code, that needs to be compiled to
|
||||
be able to run on the target platform. In theory, toolchain and operating
|
||||
system should be independent factors, but in practice there's more or less a
|
||||
one-to-one correlation between target operating system and toolchain. There are
|
||||
ongoing efforts to loosen this strict coupling between compiler and operating
|
||||
system (see [JDK-8288293](https://bugs.openjdk.org/browse/JDK-8288293)) but it
|
||||
will likely be a very long time before this goal can be realized.
|
||||
one-to-one correlation between target operating system and toolchain.
|
||||
|
||||
| Operating system | Supported toolchain |
|
||||
| ------------------ | ------------------------- |
|
||||
| Linux | gcc, clang |
|
||||
| macOS | Apple Xcode (using clang) |
|
||||
| AIX | IBM XL C/C++ |
|
||||
| Windows | Microsoft Visual Studio |
|
||||
Operating system Supported toolchain
|
||||
------------------ -------------------------
|
||||
Linux gcc, clang
|
||||
macOS Apple Xcode (using clang)
|
||||
AIX IBM XL C/C++
|
||||
Windows Microsoft Visual Studio
|
||||
|
||||
Please see the individual sections on the toolchains for version
|
||||
recommendations. As a reference, these versions of the toolchains are used, at
|
||||
@@ -330,11 +319,11 @@ possible to compile the JDK with both older and newer versions, but the closer
|
||||
you stay to this list, the more likely you are to compile successfully without
|
||||
issues.
|
||||
|
||||
| Operating system | Toolchain version |
|
||||
| ------------------ | ------------------------------------------ |
|
||||
| Linux | gcc 11.2.0 |
|
||||
| macOS | Apple Xcode 10.1 (using clang 10.0.0) |
|
||||
| Windows | Microsoft Visual Studio 2022 update 17.1.0 |
|
||||
Operating system Toolchain version
|
||||
------------------ -------------------------------------------------------
|
||||
Linux gcc 10.2.0
|
||||
macOS Apple Xcode 10.1 (using clang 10.0.0)
|
||||
Windows Microsoft Visual Studio 2019 update 16.7.2
|
||||
|
||||
All compilers are expected to be able to compile to the C99 language standard,
|
||||
as some C99 features are used in the source code. Microsoft Visual Studio
|
||||
@@ -346,7 +335,7 @@ features that it does support.
|
||||
The minimum accepted version of gcc is 5.0. Older versions will generate a warning
|
||||
by `configure` and are unlikely to work.
|
||||
|
||||
The JDK is currently known to be able to compile with at least version 11.2 of
|
||||
The JDK is currently known to be able to compile with at least version 10.2 of
|
||||
gcc.
|
||||
|
||||
In general, any version between these two should be usable.
|
||||
@@ -362,20 +351,20 @@ To use clang instead of gcc on Linux, use `--with-toolchain-type=clang`.
|
||||
|
||||
The oldest supported version of Xcode is 8.
|
||||
|
||||
You will need the Xcode command line developer tools to be able to build
|
||||
the JDK. (Actually, *only* the command line tools are needed, not the IDE.)
|
||||
You will need the Xcode command lines developers tools to be able to build
|
||||
the JDK. (Actually, *only* the command lines tools are needed, not the IDE.)
|
||||
The simplest way to install these is to run:
|
||||
```
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
When updating Xcode, it is advisable to keep an older version for building the JDK.
|
||||
To use a specific version of Xcode you have multiple options:
|
||||
|
||||
* Use `xcode-select -s` before running `configure`, e.g. `xcode-select -s /Applications/Xcode13.1.app`. The drawback is that the setting
|
||||
is system wide and you may have to revert it after an OpenJDK build.
|
||||
* Use configure option `--with-xcode-path`, e.g. `configure --with-xcode-path=/Applications/Xcode13.1.app`
|
||||
This allows using a specific Xcode version for an OpenJDK build, independently of the active Xcode version by `xcode-select`.
|
||||
It is advisable to keep an older version of Xcode for building the JDK when
|
||||
updating Xcode. This [blog page](
|
||||
http://iosdevelopertips.com/xcode/install-multiple-versions-of-xcode.html) has
|
||||
good suggestions on managing multiple Xcode versions. To use a specific version
|
||||
of Xcode, use `xcode-select -s` before running `configure`, or use
|
||||
`--with-toolchain-path` to point to the version of Xcode to use, e.g.
|
||||
`configure --with-toolchain-path=/Applications/Xcode8.app/Contents/Developer/usr/bin`
|
||||
|
||||
If you have recently (inadvertently) updated your OS and/or Xcode version, and
|
||||
the JDK can no longer be built, please see the section on [Problems with the
|
||||
@@ -385,14 +374,13 @@ available for this update.
|
||||
|
||||
### Microsoft Visual Studio
|
||||
|
||||
The minimum accepted version is Visual Studio 2019 version 16.8. (Note that this
|
||||
version is often presented as "MSVC 14.28", and reported by cl.exe as 19.28.)
|
||||
Older versions will not be accepted by `configure` and will not work. The
|
||||
maximum accepted version of Visual Studio is 2022.
|
||||
The minimum accepted version of Visual Studio is 2017. Older versions will not
|
||||
be accepted by `configure` and will not work. The maximum accepted
|
||||
version of Visual Studio is 2019.
|
||||
|
||||
If you have multiple versions of Visual Studio installed, `configure` will by
|
||||
default pick the latest. You can request a specific version to be used by
|
||||
setting `--with-toolchain-version`, e.g. `--with-toolchain-version=2022`.
|
||||
setting `--with-toolchain-version`, e.g. `--with-toolchain-version=2017`.
|
||||
|
||||
If you have Visual Studio installed but `configure` fails to detect it, it may
|
||||
be because of [spaces in path](#spaces-in-path).
|
||||
@@ -400,7 +388,7 @@ be because of [spaces in path](#spaces-in-path).
|
||||
### IBM XL C/C++
|
||||
|
||||
Please consult the AIX section of the [Supported Build Platforms](
|
||||
https://wiki.openjdk.org/display/Build/Supported+Build+Platforms) OpenJDK
|
||||
https://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms) OpenJDK
|
||||
Build Wiki page for details about which versions of XLC are supported.
|
||||
|
||||
|
||||
@@ -851,14 +839,14 @@ Suggestions for Advanced Users](#hints-and-suggestions-for-advanced-users) and
|
||||
|
||||
## Running Tests
|
||||
|
||||
Most of the JDK tests are using the [JTReg](http://openjdk.org/jtreg)
|
||||
Most of the JDK tests are using the [JTReg](http://openjdk.java.net/jtreg)
|
||||
test framework. Make sure that your configuration knows where to find your
|
||||
installation of JTReg. If this is not picked up automatically, use the
|
||||
`--with-jtreg=<path to jtreg home>` option to point to the JTReg framework.
|
||||
Note that this option should point to the JTReg home, i.e. the top directory,
|
||||
containing `lib/jtreg.jar` etc.
|
||||
|
||||
The [Adoption Group](https://wiki.openjdk.org/display/Adoption) provides
|
||||
The [Adoption Group](https://wiki.openjdk.java.net/display/Adoption) provides
|
||||
recent builds of jtreg [here](
|
||||
https://ci.adoptopenjdk.net/view/Dependencies/job/dependency_pipeline/lastSuccessfulBuild/artifact/jtreg/).
|
||||
Download the latest `.tar.gz` file, unpack it, and point `--with-jtreg` to the
|
||||
@@ -880,42 +868,6 @@ make run-test-tier1
|
||||
For more details on how to run tests, please see **Testing the JDK**
|
||||
([html](testing.html), [markdown](testing.md)).
|
||||
|
||||
## Signing
|
||||
|
||||
### macOS
|
||||
|
||||
Modern versions of macOS require applications to be signed and notarizied before
|
||||
distribution. See Apple's documentation for more background on what this means
|
||||
and how it works. To help support this, the JDK build can be configured to
|
||||
automatically sign all native binaries, and the JDK bundle, with all the options
|
||||
needed for successful notarization, as well as all the entitlements required by
|
||||
the JDK. To enable `hardened` signing, use configure parameter
|
||||
`--with-macosx-codesign=hardened` and configure the signing identity you wish to
|
||||
use with `--with-macosx-codesign-identity=<identity>`. The identity refers to a
|
||||
signing identity from Apple that needs to be preinstalled on the build host.
|
||||
|
||||
When not signing for distribution with the hardened option, the JDK build will
|
||||
still attempt to perform `adhoc` signing to add the special entitlement
|
||||
`com.apple.security.get-task-allow` to each binary. This entitlement is required
|
||||
to be able to dump core files from a process. Note that adding this entitlement
|
||||
makes the build invalid for notarization, so it is only added when signing in
|
||||
`debug` mode. To explicitly enable this kind of adhoc signing, use configure
|
||||
parameter `--with-macosx-codesign=debug`. It will be enabled by default in most
|
||||
cases.
|
||||
|
||||
It's also possible to completely disable any explicit codesign operations done
|
||||
by the JDK build using the configure parameter `--without-macosx-codesign`.
|
||||
The exact behavior then depends on the architecture. For macOS on x64, it (at
|
||||
least at the time of this writing) results in completely unsigned binaries that
|
||||
should still work fine for development and debugging purposes. On aarch64, the
|
||||
Xcode linker will apply a default "adhoc" signing, without any entitlements.
|
||||
Such a build does not allow dumping core files.
|
||||
|
||||
The default mode "auto" will try for `hardened` signing if the debug level is
|
||||
`release` and either the default identity or the specified identity is valid.
|
||||
If hardened isn't possible, then `debug` signing is chosen if it works. If
|
||||
nothing works, the codesign build step is disabled.
|
||||
|
||||
## Cross-compiling
|
||||
|
||||
Cross-compiling means using one platform (the *build* platform) to generate
|
||||
@@ -1025,16 +977,11 @@ You *must* specify the target platform when cross-compiling. Doing so will also
|
||||
automatically turn the build into a cross-compiling mode. The simplest way to
|
||||
do this is to use the `--openjdk-target` argument, e.g.
|
||||
`--openjdk-target=arm-linux-gnueabihf`. or `--openjdk-target=aarch64-oe-linux`.
|
||||
This will automatically set the `--host` and `--target` options for
|
||||
This will automatically set the `--build`, `--host` and `--target` options for
|
||||
autoconf, which can otherwise be confusing. (In autoconf terminology, the
|
||||
"target" is known as "host", and "target" is used for building a Canadian
|
||||
cross-compiler.)
|
||||
|
||||
If `--build` has not been explicitly passed to configure, `--openjdk-target`
|
||||
will autodetect the build platform and internally set the flag automatically,
|
||||
otherwise the platform that was explicitly passed to `--build` will be used
|
||||
instead.
|
||||
|
||||
### Toolchain Considerations
|
||||
|
||||
You will need two copies of your toolchain, one which generates output that can
|
||||
@@ -1333,12 +1280,10 @@ it.
|
||||
To use, setup an icecc network, and install icecc on the build machine. Then
|
||||
run `configure` using `--enable-icecc`.
|
||||
|
||||
### Using the javac server
|
||||
### Using sjavac
|
||||
|
||||
To speed up compilation of Java code, especially during incremental
|
||||
compilations, the javac server is automatically enabled in the configuration
|
||||
step by default. To explicitly enable or disable the javac server, use either
|
||||
`--enable-javac-server` or `--disable-javac-server`.
|
||||
To speed up Java compilation, especially incremental compilations, you can try
|
||||
the experimental sjavac compiler by using `--enable-sjavac`.
|
||||
|
||||
### Building the Right Target
|
||||
|
||||
@@ -1551,7 +1496,7 @@ You can run `fsutil file setshortname` in `cmd` on certain directories, such as
|
||||
|
||||
If none of the suggestions in this document helps you, or if you find what you
|
||||
believe is a bug in the build system, please contact the Build Group by sending
|
||||
a mail to [build-dev@openjdk.org](mailto:build-dev@openjdk.org).
|
||||
a mail to [build-dev@openjdk.java.net](mailto:build-dev@openjdk.java.net).
|
||||
Please include the relevant parts of the configure and/or build log.
|
||||
|
||||
If you need general help or advice about developing for the JDK, you can also
|
||||
@@ -1568,85 +1513,57 @@ https://reproducible-builds.org) for more information about the background and
|
||||
reasons for reproducible builds.
|
||||
|
||||
Currently, it is not possible to build OpenJDK fully reproducibly, but getting
|
||||
there is an ongoing effort.
|
||||
there is an ongoing effort. There are some things you can do to minimize
|
||||
non-determinism and make a larger part of the build reproducible:
|
||||
|
||||
An absolute prerequisite for building reproducible is to speficy a fixed build
|
||||
time, since time stamps are embedded in many file formats. This is done by
|
||||
setting the `SOURCE_DATE_EPOCH` environment variable, which is an [industry
|
||||
standard]( https://reproducible-builds.org/docs/source-date-epoch/), that many
|
||||
tools, such as gcc, recognize, and use in place of the current time when
|
||||
generating output.
|
||||
* Turn on build system support for reproducible builds
|
||||
|
||||
To generate reproducible builds, you must set `SOURCE_DATE_EPOCH` before running
|
||||
`configure`. The value in `SOURCE_DATE_EPOCH` will be stored in the
|
||||
configuration, and used by `make`. Setting `SOURCE_DATE_EPOCH` before running
|
||||
`make` will have no effect on the build.
|
||||
Add the flag `--enable-reproducible-build` to your `configure` command line.
|
||||
This will turn on support for reproducible builds where it could otherwise be
|
||||
lacking.
|
||||
|
||||
You must also make sure your build does not rely on `configure`'s default adhoc
|
||||
version strings. Default adhoc version strings `OPT` segment include user name
|
||||
and source directory. You can either override just the `OPT` segment using
|
||||
* Do not rely on `configure`'s default adhoc version strings
|
||||
|
||||
Default adhoc version strings OPT segment include user name, source directory
|
||||
and timestamp. You can either override just the OPT segment using
|
||||
`--with-version-opt=<any fixed string>`, or you can specify the entire version
|
||||
string using `--with-version-string=<your version>`.
|
||||
|
||||
This is a typical example of how to build the JDK in a reproducible way:
|
||||
* Specify how the build sets `SOURCE_DATE_EPOCH`
|
||||
|
||||
```
|
||||
export SOURCE_DATE_EPOCH=946684800
|
||||
bash configure --with-version-opt=adhoc
|
||||
make
|
||||
```
|
||||
The JDK build system will set the `SOURCE_DATE_EPOCH` environment variable
|
||||
during building, depending on the value of the `--with-source-date` option for
|
||||
`configure`. The default value is `updated`, which means that
|
||||
`SOURCE_DATE_EPOCH` will be set to the current time each time you are running
|
||||
`make`.
|
||||
|
||||
Note that regardless if you specify a source date for `configure` or not, the
|
||||
JDK build system will set `SOURCE_DATE_EPOCH` for all build tools when building.
|
||||
If `--with-source-date` has the value `current` (which is the default unless
|
||||
`SOURCE_DATE_EPOCH` is found by in the environment by `configure`), the source
|
||||
date value will be determined at configure time.
|
||||
The [`SOURCE_DATE_EPOCH` environment variable](
|
||||
https://reproducible-builds.org/docs/source-date-epoch/) is an industry
|
||||
standard, that many tools, such as gcc, recognize, and use in place of the
|
||||
current time when generating output.
|
||||
|
||||
There are several aspects of reproducible builds that can be individually
|
||||
adjusted by `configure` arguments. If any of these are given, they will override
|
||||
the value derived from `SOURCE_DATE_EPOCH`. These arguments are:
|
||||
For reproducible builds, you need to set this to a fixed value. You can use the
|
||||
special value `version` which will use the nominal release date for the current
|
||||
JDK version, or a value describing a date, either an epoch based timestamp as an
|
||||
integer, or a valid ISO-8601 date.
|
||||
|
||||
* `--with-source-date`
|
||||
**Hint:** If your build environment already sets `SOURCE_DATE_EPOCH`, you can
|
||||
propagate this using `--with-source-date=$SOURCE_DATE_EPOCH`.
|
||||
|
||||
This option controls how the JDK build sets `SOURCE_DATE_EPOCH` when
|
||||
building. It can be set to a value describing a date, either an epoch based
|
||||
timestamp as an integer, or a valid ISO-8601 date.
|
||||
* Specify a hotspot build time
|
||||
|
||||
It can also be set to one of the special values `current`, `updated` or
|
||||
`version`. `current` means that the time of running `configure` will be
|
||||
used. `version` will use the nominal release date for the current JDK
|
||||
version. `updated`, which means that `SOURCE_DATE_EPOCH` will be set to the
|
||||
current time each time you are running `make`. All choices, except for
|
||||
`updated`, will set a fixed value for the source date timestamp.
|
||||
Set a fixed hotspot build time. This will be included in the hotspot library
|
||||
(`libjvm.so` or `jvm.dll`) and defaults to the current time when building
|
||||
hotspot. Use `--with-hotspot-build-time=<any fixed string>` for reproducible
|
||||
builds. It's a string so you don't need to format it specifically, so e.g. `n/a`
|
||||
will do. Another solution is to use the `SOURCE_DATE_EPOCH` variable, e.g.
|
||||
`--with-hotspot-build-time=$(date --date=@$SOURCE_DATE_EPOCH)`.
|
||||
|
||||
When `SOURCE_DATE_EPOCH` is set, the default value for `--with-source-date`
|
||||
will be the value given by `SOURCE_DATE_EPOCH`. Otherwise, the default value
|
||||
is `current`.
|
||||
* Copyright year
|
||||
|
||||
* `--with-hotspot-build-time`
|
||||
|
||||
This option controls the build time string that will be included in the
|
||||
hotspot library (`libjvm.so` or `jvm.dll`). When the source date is fixed
|
||||
(e.g. by setting `SOURCE_DATE_EPOCH`), the default value for
|
||||
`--with-hotspot-build-time` will be an ISO 8601 representation of that time
|
||||
stamp. Otherwise the default value will be the current time when building
|
||||
hotspot.
|
||||
|
||||
* `--with-copyright-year`
|
||||
|
||||
This option controls the copyright year in some generated text files. When
|
||||
the source date is fixed (e.g. by setting `SOURCE_DATE_EPOCH`), the default
|
||||
value for `--with-copyright-year` will be the year of that time stamp.
|
||||
Otherwise the default is the current year at the time of running configure.
|
||||
This can be overridden by `--with-copyright-year=<year>`.
|
||||
|
||||
* `--enable-reproducible-build`
|
||||
|
||||
This option controls some additional behavior needed to make the build
|
||||
reproducible. When the source date is fixed (e.g. by setting
|
||||
`SOURCE_DATE_EPOCH`), this flag will be turned on by default. Otherwise, the
|
||||
value is determined by heuristics. If it is explicitly turned off, the build
|
||||
might not be reproducible.
|
||||
The copyright year in some generated text files are normally set to the current
|
||||
year. This can be overridden by `--with-copyright-year=<year>`. For fully
|
||||
reproducible builds, this needs to be set to a fixed value.
|
||||
|
||||
## Hints and Suggestions for Advanced Users
|
||||
|
||||
@@ -1961,7 +1878,7 @@ To analyze build performance, run with `LOG=trace` and check `$BUILD/build-trace
|
||||
Use `JOBS=1` to avoid parallelism.
|
||||
|
||||
Please check that you adhere to the [Code Conventions for the Build System](
|
||||
http://openjdk.org/groups/build/doc/code-conventions.html) before
|
||||
http://openjdk.java.net/groups/build/doc/code-conventions.html) before
|
||||
submitting patches.
|
||||
|
||||
## Contributing to the JDK
|
||||
@@ -1974,25 +1891,19 @@ However, please bear in mind that the JDK is a massive project, and we must ask
|
||||
you to follow our rules and guidelines to be able to accept your contribution.
|
||||
|
||||
The official place to start is the ['How to contribute' page](
|
||||
http://openjdk.org/contribute/). There is also an official (but somewhat
|
||||
http://openjdk.java.net/contribute/). There is also an official (but somewhat
|
||||
outdated and skimpy on details) [Developer's Guide](
|
||||
http://openjdk.org/guide/).
|
||||
http://openjdk.java.net/guide/).
|
||||
|
||||
If this seems overwhelming to you, the Adoption Group is there to help you! A
|
||||
good place to start is their ['New Contributor' page](
|
||||
https://wiki.openjdk.org/display/Adoption/New+Contributor), or start
|
||||
https://wiki.openjdk.java.net/display/Adoption/New+Contributor), or start
|
||||
reading the comprehensive [Getting Started Kit](
|
||||
https://adoptopenjdk.gitbooks.io/adoptopenjdk-getting-started-kit/en/). The
|
||||
Adoption Group will also happily answer any questions you have about
|
||||
contributing. Contact them by [mail](
|
||||
http://mail.openjdk.org/mailman/listinfo/adoption-discuss) or [IRC](
|
||||
http://openjdk.org/irc/).
|
||||
|
||||
## Editing this document
|
||||
|
||||
If you want to contribute changes to this document, edit `doc/building.md` and
|
||||
then run `make update-build-docs` to generate the same changes in
|
||||
`doc/building.html`.
|
||||
http://mail.openjdk.java.net/mailman/listinfo/adoption-discuss) or [IRC](
|
||||
http://openjdk.java.net/irc/).
|
||||
|
||||
---
|
||||
# Override styles from the base CSS file that are not ideal for this document.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,20 +55,13 @@ suburbs of Rome the rules are a little different; these differences
|
||||
can be pointed out here.
|
||||
|
||||
Proposed changes should be discussed on the
|
||||
[HotSpot Developers](mailto:hotspot-dev@openjdk.org) mailing
|
||||
list. Changes are likely to be cautious and incremental, since HotSpot
|
||||
coders have been using these guidelines for years.
|
||||
|
||||
Substantive changes are approved by
|
||||
[rough consensus](https://www.rfc-editor.org/rfc/rfc7282.html) of
|
||||
the [HotSpot Group](https://openjdk.org/census#hotspot) Members.
|
||||
[HotSpot Developers](mailto:hotspot-dev@openjdk.java.net) mailing
|
||||
list, and approved by
|
||||
[rough consensus](https://en.wikipedia.org/wiki/Rough_consensus) of
|
||||
the [HotSpot Group](https://openjdk.java.net/census#hotspot) Members.
|
||||
The Group Lead determines whether consensus has been reached.
|
||||
|
||||
Editorial changes (changes that only affect the description of HotSpot
|
||||
style, not its substance) do not require the full consensus gathering
|
||||
process. The normal HotSpot pull request process may be used for
|
||||
editorial changes, with the additional requirement that the requisite
|
||||
reviewers are also HotSpot Group Members.
|
||||
Changes are likely to be cautious and incremental, since HotSpot
|
||||
coders have been using these guidelines for years.
|
||||
|
||||
## Structure and Formatting
|
||||
|
||||
@@ -294,9 +287,7 @@ well.
|
||||
or consistency. Gratuitous whitespace changes will make integrations
|
||||
and backports more difficult.
|
||||
|
||||
* Use [One-True-Brace-Style](
|
||||
https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS)).
|
||||
The opening brace for a function or class
|
||||
* Use One-True-Brace-Style. The opening brace for a function or class
|
||||
is normally at the end of the line; it is sometimes moved to the
|
||||
beginning of the next line for emphasis. Substatements are enclosed
|
||||
in braces, even if there is only a single statement. Extremely simple
|
||||
@@ -418,7 +409,7 @@ Similar discussions for some other projects:
|
||||
* [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) —
|
||||
Currently (2020) targeting C++17.
|
||||
|
||||
* [C++11 and C++14 use in Chromium](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++-features.md) —
|
||||
* [C++11 and C++14 use in Chromium](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++11.md) —
|
||||
Categorizes features as allowed, banned, or to be discussed.
|
||||
|
||||
* [llvm Coding Standards](https://llvm.org/docs/CodingStandards.html) —
|
||||
@@ -471,9 +462,7 @@ code is disabled for some platforms.
|
||||
Rationale: HotSpot often uses "resource" or "arena" allocation. Even
|
||||
where heap allocation is used, the standard global functions are
|
||||
avoided in favor of wrappers around malloc and free that support the
|
||||
VM's Native Memory Tracking (NMT) feature. Typically, uses of the global
|
||||
operator new are inadvertent and therefore often associated with memory
|
||||
leaks.
|
||||
VM's Native Memory Tracking (NMT) feature.
|
||||
|
||||
Native memory allocation failures are often treated as non-recoverable.
|
||||
The place where "out of memory" is (first) detected may be an innocent
|
||||
@@ -550,7 +539,7 @@ turned off. Many Standard Library facilities implicitly or explicitly
|
||||
use exceptions.
|
||||
|
||||
* `assert`. An issue that is quickly encountered is the `assert` macro name
|
||||
collision ([JDK-8007770](https://bugs.openjdk.org/browse/JDK-8007770)).
|
||||
collision ([JDK-8007770](https://bugs.openjdk.java.net/browse/JDK-8007770)).
|
||||
Some mechanism for addressing this would be needed before much of the
|
||||
Standard Library could be used. (Not all Standard Library implementations
|
||||
use assert in header files, but some do.)
|
||||
@@ -573,7 +562,7 @@ There are a few exceptions to this rule.
|
||||
* `#include <new>` to use placement `new`, `std::nothrow`, and `std::nothrow_t`.
|
||||
* `#include <limits>` to use `std::numeric_limits`.
|
||||
* `#include <type_traits>`.
|
||||
* `#include <cstddef>` to use `std::nullptr_t` and `std::max_align_t`.
|
||||
* `#include <cstddef>` to use `std::nullptr_t`.
|
||||
|
||||
TODO: Rather than directly \#including (permitted) Standard Library
|
||||
headers, use a convention of \#including wrapper headers (in some
|
||||
@@ -633,7 +622,7 @@ Here are a few closely related example bugs:<br>
|
||||
### enum
|
||||
|
||||
Where appropriate, _scoped-enums_ should be used.
|
||||
([n2347](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf))
|
||||
([n2347](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf))
|
||||
|
||||
Use of _unscoped-enums_ is permitted, though ordinary constants may be
|
||||
preferable when the automatic initializer feature isn't used.
|
||||
@@ -651,79 +640,28 @@ constant members. Compilers having such bugs are no longer supported.
|
||||
Except where an enum is semantically appropriate, new code should use
|
||||
integral constants.
|
||||
|
||||
### alignas
|
||||
|
||||
_Alignment-specifiers_ (`alignas`
|
||||
[n2341](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf))
|
||||
are permitted, with restrictions.
|
||||
|
||||
_Alignment-specifiers_ are permitted when the requested alignment is a
|
||||
_fundamental alignment_ (not greater than `alignof(std::max_align_t)`
|
||||
[C++14 3.11/2](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf)).
|
||||
|
||||
_Alignment-specifiers_ with an _extended alignment_ (greater than
|
||||
`alignof(std::max_align_t)`
|
||||
[C++14 3.11/3](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf))
|
||||
may only be used to align variables with static or automatic storage duration
|
||||
([C++14 3.7.1, 3.7.3](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf)).
|
||||
As a consequence, _over-aligned types_ are forbidden; this may change if
|
||||
HotSpot updates to using C++17 or later
|
||||
([p0035r4](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0035r4.html)).
|
||||
|
||||
Large _extended alignments_ should be avoided, particularly for stack
|
||||
allocated objects. What is a large value may depend on the platform and
|
||||
configuration. There may also be hard limits for some platforms.
|
||||
|
||||
An _alignment-specifier_ must always be applied to a definition
|
||||
([C++14 10.6.2/6](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf)).
|
||||
(C++ allows an _alignment-specifier_ to optionally also be applied to a
|
||||
declaration, so long as the definition has equivalent alignment. There isn't
|
||||
any known benefit from duplicating the alignment in a non-definition
|
||||
declaration, so such duplication should be avoided in HotSpot code.)
|
||||
|
||||
Enumerations are forbidden from having _alignment-specifiers_. Aligned
|
||||
enumerations were originally permitted but insufficiently specified, and were
|
||||
later (C++20) removed
|
||||
([CWG 2354](https://cplusplus.github.io/CWG/issues/2354.html)).
|
||||
Permitting such usage in HotSpot now would just cause problems in the future.
|
||||
|
||||
_Alignment-specifiers_ are forbidden in `typedef` and _alias-declarations_.
|
||||
This may work or may have worked in some versions of some compilers, but was
|
||||
later (C++14) explicitly disallowed
|
||||
([CWG 1437](https://cplusplus.github.io/CWG/issues/1437.html)).
|
||||
|
||||
The HotSpot macro `ATTRIBUTE_ALIGNED` provides similar capabilities for
|
||||
platforms that define it. This macro predates the use by HotSpot of C++
|
||||
versions providing `alignas`. New code should use `alignas`.
|
||||
|
||||
### thread_local
|
||||
|
||||
Avoid use of `thread_local`
|
||||
Do not use `thread_local`
|
||||
([n2659](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm));
|
||||
and instead, use the HotSpot macro `THREAD_LOCAL`, for which the initializer must
|
||||
be a constant expression. When `thread_local` must be used, use the Hotspot macro
|
||||
`APPROVED_CPP_THREAD_LOCAL` to indicate that the use has been given appropriate
|
||||
consideration.
|
||||
instead, use the HotSpot macro `THREAD_LOCAL`. The initializer must
|
||||
be a constant expression.
|
||||
|
||||
As was discussed in the review for
|
||||
[JDK-8230877](https://mail.openjdk.org/pipermail/hotspot-dev/2019-September/039487.html),
|
||||
[JDK-8230877](https://mail.openjdk.java.net/pipermail/hotspot-dev/2019-September/039487.html),
|
||||
`thread_local` allows dynamic initialization and destruction
|
||||
semantics. However, that support requires a run-time penalty for
|
||||
references to non-function-local `thread_local` variables defined in a
|
||||
different translation unit, even if they don't need dynamic
|
||||
initialization. Dynamic initialization and destruction of
|
||||
non-local `thread_local` variables also has the same ordering
|
||||
problems as for ordinary non-local variables. So we avoid use of
|
||||
`thread_local` in general, limiting its use to only those cases where dynamic
|
||||
initialization or destruction are essential. See
|
||||
[JDK-8282469](https://bugs.openjdk.org/browse/JDK-8282469)
|
||||
for further discussion.
|
||||
namespace-scoped thread local variables also has the same ordering
|
||||
problems as for ordinary namespace-scoped variables.
|
||||
|
||||
### nullptr
|
||||
|
||||
Prefer `nullptr`
|
||||
([n2431](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf))
|
||||
to `NULL`. Don't use (constexpr or literal) 0 for pointers.
|
||||
to `NULL`. Don't use (constexpr or literal) 0 for pointers.
|
||||
|
||||
For historical reasons there are widespread uses of both `NULL` and of
|
||||
integer 0 as a pointer value.
|
||||
@@ -992,7 +930,7 @@ References:
|
||||
* Generalized lambda capture (init-capture) ([N3648])
|
||||
* Generic (polymorphic) lambda expressions ([N3649])
|
||||
|
||||
[n2657]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm
|
||||
[n2657]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm
|
||||
[n2927]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2927.pdf
|
||||
[N3648]: https://isocpp.org/files/papers/N3648.html
|
||||
[N3649]: https://isocpp.org/files/papers/N3649.html
|
||||
@@ -1030,34 +968,10 @@ References from C++23
|
||||
|
||||
[p1102r2]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1102r2.html
|
||||
|
||||
### Inheriting constructors
|
||||
|
||||
Do not use _inheriting constructors_
|
||||
([n2540](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm)).
|
||||
|
||||
C++11 provides simple syntax allowing a class to inherit the constructors of a
|
||||
base class. Unfortunately there are a number of problems with the original
|
||||
specification, and C++17 contains significant revisions ([p0136r1] opens with
|
||||
a list of 8 Core Issues). Since HotSpot doesn't support use of C++17, use of
|
||||
inherited constructors could run into those problems. Such uses might also
|
||||
change behavior in a future HotSpot update to use C++17 or later, potentially
|
||||
in subtle ways that could lead to hard to diagnose problems. Because of this,
|
||||
HotSpot code must not use inherited constructors.
|
||||
|
||||
Note that gcc7 provides the `-fnew-inheriting-ctors` option to use the
|
||||
[p0136r1] semantics. This is enabled by default when using C++17 or later.
|
||||
It is also enabled by default for `fabi-version=11` (introduced by gcc7) or
|
||||
higher when using C++11/14, as the change is considered a Defect Report that
|
||||
applies to those versions. Earlier versions of gcc don't have that option,
|
||||
and other supported compilers may not have anything similar.
|
||||
|
||||
[p0136r1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r1.html
|
||||
"p0136r1"
|
||||
|
||||
### Additional Permitted Features
|
||||
|
||||
* `constexpr`
|
||||
([n2235](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf))
|
||||
([n2235](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf))
|
||||
([n3652](https://isocpp.org/files/papers/N3652.html))
|
||||
|
||||
* Sized deallocation
|
||||
@@ -1112,9 +1026,6 @@ and other supported compilers may not have anything similar.
|
||||
([n2930](http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html))
|
||||
([range-for](https://en.cppreference.com/w/cpp/language/range-for))
|
||||
|
||||
* Unrestricted Unions
|
||||
([n2544](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf))
|
||||
|
||||
### Excluded Features
|
||||
|
||||
* New string and character literals
|
||||
@@ -1146,7 +1057,7 @@ namespace std;` to avoid needing to qualify Standard Library names.
|
||||
([n2179](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html)) —
|
||||
HotSpot does not permit the use of exceptions, so this feature isn't useful.
|
||||
|
||||
* Avoid non-local variables with non-constexpr initialization.
|
||||
* Avoid namespace-scoped variables with non-constexpr initialization.
|
||||
In particular, avoid variables with types requiring non-trivial
|
||||
initialization or destruction. Initialization order problems can be
|
||||
difficult to deal with and lead to surprises, as can destruction
|
||||
@@ -1165,14 +1076,16 @@ normal expected behavior of the operation.
|
||||
conversion operators. (Note that conversion to `bool` isn't needed
|
||||
in HotSpot code because of the "no implicit boolean" guideline.)
|
||||
|
||||
* Avoid `goto` statements.
|
||||
* Avoid covariant return types.
|
||||
|
||||
* Avoid `goto` statements.
|
||||
|
||||
### Undecided Features
|
||||
|
||||
This list is incomplete; it serves to explicitly call out some
|
||||
features that have not yet been discussed.
|
||||
|
||||
* Trailing return type syntax for functions
|
||||
* Trailing return type syntax for functions
|
||||
([n2541](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm))
|
||||
|
||||
* Variable templates
|
||||
@@ -1186,7 +1099,7 @@ features that have not yet been discussed.
|
||||
|
||||
* Rvalue references and move semantics
|
||||
|
||||
[ADL]: https://en.cppreference.com/w/cpp/language/adl
|
||||
[ADL]: https://en.cppreference.com/w/cpp/language/adl
|
||||
"Argument Dependent Lookup"
|
||||
|
||||
[ODR]: https://en.cppreference.com/w/cpp/language/definition
|
||||
|
||||
@@ -5,19 +5,11 @@
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>Native/Unit Test Development Guidelines</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
<style type="text/css">
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" />
|
||||
<!--[if lt IE 9]>
|
||||
@@ -28,442 +20,174 @@
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">Native/Unit Test Development Guidelines</h1>
|
||||
</header>
|
||||
<nav id="TOC" role="doc-toc">
|
||||
<nav id="TOC">
|
||||
<ul>
|
||||
<li><a href="#good-test-properties" id="toc-good-test-properties">Good
|
||||
test properties</a>
|
||||
<ul>
|
||||
<li><a href="#lightness" id="toc-lightness">Lightness</a></li>
|
||||
<li><a href="#isolation" id="toc-isolation">Isolation</a></li>
|
||||
<li><a href="#atomicity-and-self-containment"
|
||||
id="toc-atomicity-and-self-containment">Atomicity and
|
||||
self-containment</a></li>
|
||||
<li><a href="#repeatability"
|
||||
id="toc-repeatability">Repeatability</a></li>
|
||||
<li><a href="#informativeness"
|
||||
id="toc-informativeness">Informativeness</a></li>
|
||||
<li><a href="#testing-instead-of-visiting"
|
||||
id="toc-testing-instead-of-visiting">Testing instead of
|
||||
visiting</a></li>
|
||||
<li><a href="#nearness" id="toc-nearness">Nearness</a></li>
|
||||
<li><a href="#good-test-properties">Good test properties</a><ul>
|
||||
<li><a href="#lightness">Lightness</a></li>
|
||||
<li><a href="#isolation">Isolation</a></li>
|
||||
<li><a href="#atomicity-and-self-containment">Atomicity and self-containment</a></li>
|
||||
<li><a href="#repeatability">Repeatability</a></li>
|
||||
<li><a href="#informativeness">Informativeness</a></li>
|
||||
<li><a href="#testing-instead-of-visiting">Testing instead of visiting</a></li>
|
||||
<li><a href="#nearness">Nearness</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#asserts" id="toc-asserts">Asserts</a>
|
||||
<ul>
|
||||
<li><a href="#several-checks" id="toc-several-checks">Several
|
||||
checks</a></li>
|
||||
<li><a href="#first-parameter-is-expected-value"
|
||||
id="toc-first-parameter-is-expected-value">First parameter is expected
|
||||
value</a></li>
|
||||
<li><a href="#floating-point-comparison"
|
||||
id="toc-floating-point-comparison">Floating-point comparison</a></li>
|
||||
<li><a href="#c-string-comparison" id="toc-c-string-comparison">C string
|
||||
comparison</a></li>
|
||||
<li><a href="#error-messages" id="toc-error-messages">Error
|
||||
messages</a></li>
|
||||
<li><a href="#uncluttered-output"
|
||||
id="toc-uncluttered-output">Uncluttered output</a></li>
|
||||
<li><a href="#failures-propagation"
|
||||
id="toc-failures-propagation">Failures propagation</a></li>
|
||||
<li><a href="#asserts">Asserts</a><ul>
|
||||
<li><a href="#several-checks">Several checks</a></li>
|
||||
<li><a href="#first-parameter-is-expected-value">First parameter is expected value</a></li>
|
||||
<li><a href="#floating-point-comparison">Floating-point comparison</a></li>
|
||||
<li><a href="#c-string-comparison">C string comparison</a></li>
|
||||
<li><a href="#error-messages">Error messages</a></li>
|
||||
<li><a href="#uncluttered-output">Uncluttered output</a></li>
|
||||
<li><a href="#failures-propagation">Failures propagation</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#naming-and-grouping" id="toc-naming-and-grouping">Naming
|
||||
and Grouping</a>
|
||||
<ul>
|
||||
<li><a href="#test-group-names" id="toc-test-group-names">Test group
|
||||
names</a></li>
|
||||
<li><a href="#filename" id="toc-filename">Filename</a></li>
|
||||
<li><a href="#file-location" id="toc-file-location">File
|
||||
location</a></li>
|
||||
<li><a href="#test-names" id="toc-test-names">Test names</a></li>
|
||||
<li><a href="#fixture-classes" id="toc-fixture-classes">Fixture
|
||||
classes</a></li>
|
||||
<li><a href="#friend-classes" id="toc-friend-classes">Friend
|
||||
classes</a></li>
|
||||
<li><a href="#oscpu-specific-tests" id="toc-oscpu-specific-tests">OS/CPU
|
||||
specific tests</a></li>
|
||||
<li><a href="#naming-and-grouping">Naming and Grouping</a><ul>
|
||||
<li><a href="#test-group-names">Test group names</a></li>
|
||||
<li><a href="#filename">Filename</a></li>
|
||||
<li><a href="#file-location">File location</a></li>
|
||||
<li><a href="#test-names">Test names</a></li>
|
||||
<li><a href="#fixture-classes">Fixture classes</a></li>
|
||||
<li><a href="#friend-classes">Friend classes</a></li>
|
||||
<li><a href="#oscpu-specific-tests">OS/CPU specific tests</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#miscellaneous" id="toc-miscellaneous">Miscellaneous</a>
|
||||
<ul>
|
||||
<li><a href="#hotspot-style" id="toc-hotspot-style">Hotspot
|
||||
style</a></li>
|
||||
<li><a href="#codetest-metrics" id="toc-codetest-metrics">Code/test
|
||||
metrics</a></li>
|
||||
<li><a href="#access-to-non-public-members"
|
||||
id="toc-access-to-non-public-members">Access to non-public
|
||||
members</a></li>
|
||||
<li><a href="#death-tests" id="toc-death-tests">Death tests</a></li>
|
||||
<li><a href="#external-flags" id="toc-external-flags">External
|
||||
flags</a></li>
|
||||
<li><a href="#test-specific-flags"
|
||||
id="toc-test-specific-flags">Test-specific flags</a></li>
|
||||
<li><a href="#flag-restoring" id="toc-flag-restoring">Flag
|
||||
restoring</a></li>
|
||||
<li><a href="#googletest-documentation"
|
||||
id="toc-googletest-documentation">GoogleTest documentation</a></li>
|
||||
<li><a href="#miscellaneous">Miscellaneous</a><ul>
|
||||
<li><a href="#hotspot-style">Hotspot style</a></li>
|
||||
<li><a href="#codetest-metrics">Code/test metrics</a></li>
|
||||
<li><a href="#access-to-non-public-members">Access to non-public members</a></li>
|
||||
<li><a href="#death-tests">Death tests</a></li>
|
||||
<li><a href="#external-flags">External flags</a></li>
|
||||
<li><a href="#test-specific-flags">Test-specific flags</a></li>
|
||||
<li><a href="#flag-restoring">Flag restoring</a></li>
|
||||
<li><a href="#googletest-documentation">GoogleTest documentation</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#todo" id="toc-todo">TODO</a></li>
|
||||
<li><a href="#todo">TODO</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<p>The purpose of these guidelines is to establish a shared vision on
|
||||
what kind of native tests and how we want to develop them for Hotspot
|
||||
using GoogleTest. Hence these guidelines include style items as well as
|
||||
test approach items.</p>
|
||||
<p>First section of this document describes properties of good tests
|
||||
which are common for almost all types of test regardless of language,
|
||||
framework, etc. Further sections provide recommendations to achieve
|
||||
those properties and other HotSpot and/or GoogleTest specific
|
||||
guidelines.</p>
|
||||
<p>The purpose of these guidelines is to establish a shared vision on what kind of native tests and how we want to develop them for Hotspot using GoogleTest. Hence these guidelines include style items as well as test approach items.</p>
|
||||
<p>First section of this document describes properties of good tests which are common for almost all types of test regardless of language, framework, etc. Further sections provide recommendations to achieve those properties and other HotSpot and/or GoogleTest specific guidelines.</p>
|
||||
<h2 id="good-test-properties">Good test properties</h2>
|
||||
<h3 id="lightness">Lightness</h3>
|
||||
<p>Use the most lightweight type of tests.</p>
|
||||
<p>In Hotspot, there are 3 different types of tests regarding their
|
||||
dependency on a JVM, each next level is slower than previous</p>
|
||||
<p>In Hotspot, there are 3 different types of tests regarding their dependency on a JVM, each next level is slower than previous</p>
|
||||
<ul>
|
||||
<li><p><code>TEST</code> : a test does not depend on a JVM</p></li>
|
||||
<li><p><code>TEST_VM</code> : a test does depend on an initialized JVM,
|
||||
but are supposed not to break a JVM, i.e. leave it in a workable
|
||||
state.</p></li>
|
||||
<li><p><code>TEST_OTHER_VM</code> : a test depends on a JVM and requires
|
||||
a freshly initialized JVM or leaves a JVM in non-workable state</p></li>
|
||||
<li><p><code>TEST_VM</code> : a test does depend on an initialized JVM, but are supposed not to break a JVM, i.e. leave it in a workable state.</p></li>
|
||||
<li><p><code>TEST_OTHER_VM</code> : a test depends on a JVM and requires a freshly initialized JVM or leaves a JVM in non-workable state</p></li>
|
||||
</ul>
|
||||
<h3 id="isolation">Isolation</h3>
|
||||
<p>Tests have to be isolated: not to have visible side-effects,
|
||||
influences on other tests results.</p>
|
||||
<p>Results of one test should not depend on test execution order, other
|
||||
tests, otherwise it is becoming almost impossible to find out why a test
|
||||
failed. Due to hotspot-specific, it is not so easy to get a full
|
||||
isolation, e.g. we share an initialized JVM between all
|
||||
<code>TEST_VM</code> tests, so if your test changes JVM's state too
|
||||
drastically and does not change it back, you had better consider
|
||||
<code>TEST_OTHER_VM</code>.</p>
|
||||
<h3 id="atomicity-and-self-containment">Atomicity and
|
||||
self-containment</h3>
|
||||
<p>Tests should be <em>atomic</em> and <em>self-contained</em> at the
|
||||
same time.</p>
|
||||
<p>One test should check a particular part of a class, subsystem,
|
||||
functionality, etc. Then it is quite easy to determine what parts of a
|
||||
product are broken basing on test failures. On the other hand, a test
|
||||
should test that part more-or-less entirely, because when one sees a
|
||||
test <code>FooTest::bar</code>, they assume all aspects of bar from
|
||||
<code>Foo</code> are tested.</p>
|
||||
<p>However, it is impossible to cover all aspects even of a method, not
|
||||
to mention a subsystem. In such cases, it is recommended to have several
|
||||
tests, one for each aspect of a thing under test. For example one test
|
||||
to tests how <code>Foo::bar</code> works if an argument is
|
||||
<code>null</code>, another test to test how it works if an argument is
|
||||
acceptable but <code>Foo</code> is not in the right state to accept it
|
||||
and so on. This helps not only to make tests atomic, self-contained but
|
||||
also makes test name self-descriptive (discussed in more details in <a
|
||||
href="#test-names">Test names</a>).</p>
|
||||
<p>Tests have to be isolated: not to have visible side-effects, influences on other tests results.</p>
|
||||
<p>Results of one test should not depend on test execution order, other tests, otherwise it is becoming almost impossible to find out why a test failed. Due to hotspot-specific, it is not so easy to get a full isolation, e.g. we share an initialized JVM between all <code>TEST_VM</code> tests, so if your test changes JVM's state too drastically and does not change it back, you had better consider <code>TEST_OTHER_VM</code>.</p>
|
||||
<h3 id="atomicity-and-self-containment">Atomicity and self-containment</h3>
|
||||
<p>Tests should be <em>atomic</em> and <em>self-contained</em> at the same time.</p>
|
||||
<p>One test should check a particular part of a class, subsystem, functionality, etc. Then it is quite easy to determine what parts of a product are broken basing on test failures. On the other hand, a test should test that part more-or-less entirely, because when one sees a test <code>FooTest::bar</code>, they assume all aspects of bar from <code>Foo</code> are tested.</p>
|
||||
<p>However, it is impossible to cover all aspects even of a method, not to mention a subsystem. In such cases, it is recommended to have several tests, one for each aspect of a thing under test. For example one test to tests how <code>Foo::bar</code> works if an argument is <code>null</code>, another test to test how it works if an argument is acceptable but <code>Foo</code> is not in the right state to accept it and so on. This helps not only to make tests atomic, self-contained but also makes test name self-descriptive (discussed in more details in <a href="#test-names">Test names</a>).</p>
|
||||
<h3 id="repeatability">Repeatability</h3>
|
||||
<p>Tests have to be repeatable.</p>
|
||||
<p>Reproducibility is very crucial for a test. No one likes sporadic
|
||||
test failures, they are hard to investigate, fix and verify a fix.</p>
|
||||
<p>In some cases, it is quite hard to write a 100% repeatable test,
|
||||
since besides a test there can be other moving parts, e.g. in case of
|
||||
<code>TEST_VM</code> there are several concurrently running threads.
|
||||
Despite this, we should try to make a test as reproducible as
|
||||
possible.</p>
|
||||
<p>Reproducibility is very crucial for a test. No one likes sporadic test failures, they are hard to investigate, fix and verify a fix.</p>
|
||||
<p>In some cases, it is quite hard to write a 100% repeatable test, since besides a test there can be other moving parts, e.g. in case of <code>TEST_VM</code> there are several concurrently running threads. Despite this, we should try to make a test as reproducible as possible.</p>
|
||||
<h3 id="informativeness">Informativeness</h3>
|
||||
<p>In case of a failure, a test should be as <em>informative</em> as
|
||||
possible.</p>
|
||||
<p>Having more information about a test failure than just compared
|
||||
values can be very useful for failure troubleshooting, it can reduce or
|
||||
even completely eliminate debugging hours. This is even more important
|
||||
in case of not 100% reproducible failures.</p>
|
||||
<p>Achieving this property, one can easily make a test too verbose, so
|
||||
it will be really hard to find useful information in the ocean of
|
||||
useless information. Hence they should not only think about how to
|
||||
provide <a href="#error-messages">good information</a>, but also <a
|
||||
href="#uncluttered-output">when to do it</a>.</p>
|
||||
<p>In case of a failure, a test should be as <em>informative</em> as possible.</p>
|
||||
<p>Having more information about a test failure than just compared values can be very useful for failure troubleshooting, it can reduce or even completely eliminate debugging hours. This is even more important in case of not 100% reproducible failures.</p>
|
||||
<p>Achieving this property, one can easily make a test too verbose, so it will be really hard to find useful information in the ocean of useless information. Hence they should not only think about how to provide <a href="#error-messages">good information</a>, but also <a href="#uncluttered-output">when to do it</a>.</p>
|
||||
<h3 id="testing-instead-of-visiting">Testing instead of visiting</h3>
|
||||
<p>Tests should <em>test</em>.</p>
|
||||
<p>It is not enough just to "visit" some code, a test should check that
|
||||
code does that it has to do, compare return values with expected values,
|
||||
check that desired side effects are done, and undesired are not, and so
|
||||
on. In other words, a test should contain at least one GoogleTest
|
||||
assertion and do not rely on JVM asserts.</p>
|
||||
<p>Generally speaking to write a good test, one should create a model of
|
||||
the system under tests, a model of possible bugs (or bugs which one
|
||||
wants to find) and design tests using those models.</p>
|
||||
<p>It is not enough just to "visit" some code, a test should check that code does that it has to do, compare return values with expected values, check that desired side effects are done, and undesired are not, and so on. In other words, a test should contain at least one GoogleTest assertion and do not rely on JVM asserts.</p>
|
||||
<p>Generally speaking to write a good test, one should create a model of the system under tests, a model of possible bugs (or bugs which one wants to find) and design tests using those models.</p>
|
||||
<h3 id="nearness">Nearness</h3>
|
||||
<p>Prefer having checks inside test code.</p>
|
||||
<p>Not only does having test logic outside, e.g. verification method,
|
||||
depending on asserts in product code contradict with several items above
|
||||
but also decreases test’s readability and stability. It is much easier
|
||||
to understand that a test is testing when all testing logic is located
|
||||
inside a test or nearby in shared test libraries. As a rule of thumb,
|
||||
the closer a check to a test, the better.</p>
|
||||
<p>Not only does having test logic outside, e.g. verification method, depending on asserts in product code contradict with several items above but also decreases test’s readability and stability. It is much easier to understand that a test is testing when all testing logic is located inside a test or nearby in shared test libraries. As a rule of thumb, the closer a check to a test, the better.</p>
|
||||
<h2 id="asserts">Asserts</h2>
|
||||
<h3 id="several-checks">Several checks</h3>
|
||||
<p>Prefer <code>EXPECT</code> over <code>ASSERT</code> if possible.</p>
|
||||
<p>This is related to the <a href="#informativeness">informativeness</a>
|
||||
property of tests, information for other checks can help to better
|
||||
localize a defect’s root-cause. One should use <code>ASSERT</code> if it
|
||||
is impossible to continue test execution or if it does not make much
|
||||
sense. Later in the text, <code>EXPECT</code> forms will be used to
|
||||
refer to both <code>ASSERT/EXPECT</code>.</p>
|
||||
<p>When it is possible to make several different checks, but impossible
|
||||
to continue test execution if at least one check fails, you can use
|
||||
<code>::testing::Test::HasNonfatalFailure()</code> function. The
|
||||
recommended way to express that is
|
||||
<code>ASSERT_FALSE(::testing::Test::HasNonfatalFailure())</code>.
|
||||
Besides making it clear why a test is aborted, it also allows you to
|
||||
provide more information about a failure.</p>
|
||||
<h3 id="first-parameter-is-expected-value">First parameter is expected
|
||||
value</h3>
|
||||
<p>In all equality assertions, expected values should be passed as the
|
||||
first parameter.</p>
|
||||
<p>This convention is adopted by GoogleTest, and there is a slight
|
||||
difference in how GoogleTest treats parameters, the most important one
|
||||
is <code>null</code> detection. Due to different reasons,
|
||||
<code>null</code> detection is enabled only for the first parameter,
|
||||
that is to said <code>EXPECT_EQ(NULL, object)</code> checks that object
|
||||
is <code>null</code>, while <code>EXPECT_EQ(object, NULL)</code> checks
|
||||
that object equals to <code>NULL</code>, GoogleTest is very strict
|
||||
regarding types of compared values so the latter will generates a
|
||||
compile-time error.</p>
|
||||
<p>This is related to the <a href="#informativeness">informativeness</a> property of tests, information for other checks can help to better localize a defect’s root-cause. One should use <code>ASSERT</code> if it is impossible to continue test execution or if it does not make much sense. Later in the text, <code>EXPECT</code> forms will be used to refer to both <code>ASSERT/EXPECT</code>.</p>
|
||||
<p>When it is possible to make several different checks, but impossible to continue test execution if at least one check fails, you can use <code>::testing::Test::HasNonfatalFailure()</code> function. The recommended way to express that is <code>ASSERT_FALSE(::testing::Test::HasNonfatalFailure())</code>. Besides making it clear why a test is aborted, it also allows you to provide more information about a failure.</p>
|
||||
<h3 id="first-parameter-is-expected-value">First parameter is expected value</h3>
|
||||
<p>In all equality assertions, expected values should be passed as the first parameter.</p>
|
||||
<p>This convention is adopted by GoogleTest, and there is a slight difference in how GoogleTest treats parameters, the most important one is <code>null</code> detection. Due to different reasons, <code>null</code> detection is enabled only for the first parameter, that is to said <code>EXPECT_EQ(NULL, object)</code> checks that object is <code>null</code>, while <code>EXPECT_EQ(object, NULL)</code> checks that object equals to <code>NULL</code>, GoogleTest is very strict regarding types of compared values so the latter will generates a compile-time error.</p>
|
||||
<h3 id="floating-point-comparison">Floating-point comparison</h3>
|
||||
<p>Use floating-point special macros to compare
|
||||
<code>float/double</code> values.</p>
|
||||
<p>Because of floating-point number representations and round-off
|
||||
errors, regular equality comparison will not return true in most cases.
|
||||
There are special <code>EXPECT_FLOAT_EQ/EXPECT_DOUBLE_EQ</code>
|
||||
assertions which check that the distance between compared values is not
|
||||
more than 4 ULPs, there is also <code>EXPECT_NEAR(v1, v2, eps)</code>
|
||||
which checks that the absolute value of the difference between
|
||||
<code>v1</code> and <code>v2</code> is not greater than
|
||||
<code>eps</code>.</p>
|
||||
<p>Use floating-point special macros to compare <code>float/double</code> values.</p>
|
||||
<p>Because of floating-point number representations and round-off errors, regular equality comparison will not return true in most cases. There are special <code>EXPECT_FLOAT_EQ/EXPECT_DOUBLE_EQ</code> assertions which check that the distance between compared values is not more than 4 ULPs, there is also <code>EXPECT_NEAR(v1, v2, eps)</code> which checks that the absolute value of the difference between <code>v1</code> and <code>v2</code> is not greater than <code>eps</code>.</p>
|
||||
<h3 id="c-string-comparison">C string comparison</h3>
|
||||
<p>Use string special macros for C strings comparisons.</p>
|
||||
<p><code>EXPECT_EQ</code> just compares pointers’ values, which is
|
||||
hardly what one wants comparing C strings. GoogleTest provides
|
||||
<code>EXPECT_STREQ</code> and <code>EXPECT_STRNE</code> macros to
|
||||
compare C string contents. There are also case-insensitive versions
|
||||
<code>EXPECT_STRCASEEQ</code>, <code>EXPECT_STRCASENE</code>.</p>
|
||||
<p><code>EXPECT_EQ</code> just compares pointers’ values, which is hardly what one wants comparing C strings. GoogleTest provides <code>EXPECT_STREQ</code> and <code>EXPECT_STRNE</code> macros to compare C string contents. There are also case-insensitive versions <code>EXPECT_STRCASEEQ</code>, <code>EXPECT_STRCASENE</code>.</p>
|
||||
<h3 id="error-messages">Error messages</h3>
|
||||
<p>Provide informative, but not too verbose error messages.</p>
|
||||
<p>All GoogleTest asserts print compared expressions and their values,
|
||||
so there is no need to have them in error messages. Asserts print only
|
||||
compared values, they do not print any of interim variables, e.g.
|
||||
<code>ASSERT_TRUE((val1 == val2 && isFail(foo(8)) || i == 18)</code>
|
||||
prints only one value. If you use some complex predicates, please
|
||||
consider <code>EXPECT_PRED*</code> or <code>EXPECT_FORMAT_PRED</code>
|
||||
assertions family, they check that a predicate returns true/success and
|
||||
print out all parameters values.</p>
|
||||
<p>However in some cases, default information is not enough, a commonly
|
||||
used example is an assert inside a loop, GoogleTest will not print
|
||||
iteration values (unless it is an assert's parameter). Other
|
||||
demonstrative examples are printing error code and a corresponding error
|
||||
message; printing internal states which might have an impact on results.
|
||||
One should add this information to assert message using
|
||||
<code><<</code> operator.</p>
|
||||
<p>All GoogleTest asserts print compared expressions and their values, so there is no need to have them in error messages. Asserts print only compared values, they do not print any of interim variables, e.g. <code>ASSERT_TRUE((val1 == val2 && isFail(foo(8)) || i == 18)</code> prints only one value. If you use some complex predicates, please consider <code>EXPECT_PRED*</code> or <code>EXPECT_FORMAT_PRED</code> assertions family, they check that a predicate returns true/success and print out all parameters values.</p>
|
||||
<p>However in some cases, default information is not enough, a commonly used example is an assert inside a loop, GoogleTest will not print iteration values (unless it is an assert's parameter). Other demonstrative examples are printing error code and a corresponding error message; printing internal states which might have an impact on results. One should add this information to assert message using <code><<</code> operator.</p>
|
||||
<h3 id="uncluttered-output">Uncluttered output</h3>
|
||||
<p>Print information only if it is needed.</p>
|
||||
<p>Too verbose tests which print all information even if they pass are
|
||||
very bad practice. They just pollute output, so it becomes harder to
|
||||
find useful information. In order not print information till it is
|
||||
really needed, one should consider saving it to a temporary buffer and
|
||||
pass to an assert. <a
|
||||
href="https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp"
|
||||
class="uri">https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp</a>
|
||||
has a good example how to do that.</p>
|
||||
<p>Too verbose tests which print all information even if they pass are very bad practice. They just pollute output, so it becomes harder to find useful information. In order not print information till it is really needed, one should consider saving it to a temporary buffer and pass to an assert. <a href="https://hg.openjdk.java.net/jdk/jdk/file/tip/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp" class="uri">https://hg.openjdk.java.net/jdk/jdk/file/tip/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp</a> has a good example how to do that.</p>
|
||||
<h3 id="failures-propagation">Failures propagation</h3>
|
||||
<p>Wrap a subroutine call into <code>EXPECT_NO_FATAL_FAILURE</code>
|
||||
macro to propagate failures.</p>
|
||||
<p><code>ASSERT</code> and <code>FAIL</code> abort only the current
|
||||
function, so if you have them in a subroutine, a test will not be
|
||||
aborted after the subroutine even if <code>ASSERT</code> or
|
||||
<code>FAIL</code> fails. You should call such subroutines in
|
||||
<code>ASSERT_NO_FATAL_FAILURE</code> macro to propagate fatal failures
|
||||
and abort a test. <code>(EXPECT|ASSERT)_NO_FATAL_FAILURE</code> can also
|
||||
be used to provide more information.</p>
|
||||
<p>Due to obvious reasons, there are no
|
||||
<code>(EXPECT|ASSERT)_NO_NONFATAL_FAILURE</code> macros. However, if you
|
||||
need to check if a subroutine generated a nonfatal failure (failed an
|
||||
<code>EXPECT</code>), you can use
|
||||
<code>::testing::Test::HasNonfatalFailure</code> function, or
|
||||
<code>::testing::Test::HasFailure</code> function to check if a
|
||||
subroutine generated any failures, see <a href="#several-checks">Several
|
||||
checks</a>.</p>
|
||||
<p>Wrap a subroutine call into <code>EXPECT_NO_FATAL_FAILURE</code> macro to propagate failures.</p>
|
||||
<p><code>ASSERT</code> and <code>FAIL</code> abort only the current function, so if you have them in a subroutine, a test will not be aborted after the subroutine even if <code>ASSERT</code> or <code>FAIL</code> fails. You should call such subroutines in <code>ASSERT_NO_FATAL_FAILURE</code> macro to propagate fatal failures and abort a test. <code>(EXPECT|ASSERT)_NO_FATAL_FAILURE</code> can also be used to provide more information.</p>
|
||||
<p>Due to obvious reasons, there are no <code>(EXPECT|ASSERT)_NO_NONFATAL_FAILURE</code> macros. However, if you need to check if a subroutine generated a nonfatal failure (failed an <code>EXPECT</code>), you can use <code>::testing::Test::HasNonfatalFailure</code> function, or <code>::testing::Test::HasFailure</code> function to check if a subroutine generated any failures, see <a href="#several-checks">Several checks</a>.</p>
|
||||
<h2 id="naming-and-grouping">Naming and Grouping</h2>
|
||||
<h3 id="test-group-names">Test group names</h3>
|
||||
<p>Test group names should be in CamelCase, start and end with a letter.
|
||||
A test group should be named after tested class, functionality,
|
||||
subsystem, etc.</p>
|
||||
<p>This naming scheme helps to find tests, filter them and simplifies
|
||||
test failure analysis. For example, class <code>Foo</code> - test group
|
||||
<code>Foo</code>, compiler logging subsystem - test group
|
||||
<code>CompilerLogging</code>, G1 GC — test group <code>G1GC</code>, and
|
||||
so forth.</p>
|
||||
<p>Test group names should be in CamelCase, start and end with a letter. A test group should be named after tested class, functionality, subsystem, etc.</p>
|
||||
<p>This naming scheme helps to find tests, filter them and simplifies test failure analysis. For example, class <code>Foo</code> - test group <code>Foo</code>, compiler logging subsystem - test group <code>CompilerLogging</code>, G1 GC — test group <code>G1GC</code>, and so forth.</p>
|
||||
<h3 id="filename">Filename</h3>
|
||||
<p>A test file must have <code>test_</code> prefix and <code>.cpp</code>
|
||||
suffix.</p>
|
||||
<p>Both are actually requirements from the current build system to
|
||||
recognize your tests.</p>
|
||||
<p>A test file must have <code>test_</code> prefix and <code>.cpp</code> suffix.</p>
|
||||
<p>Both are actually requirements from the current build system to recognize your tests.</p>
|
||||
<h3 id="file-location">File location</h3>
|
||||
<p>Test file location should reflect a location of the tested part of
|
||||
the product.</p>
|
||||
<p>Test file location should reflect a location of the tested part of the product.</p>
|
||||
<ul>
|
||||
<li><p>All unit tests for a class from <code>foo/bar/baz.cpp</code>
|
||||
should be placed <code>foo/bar/test_baz.cpp</code> in
|
||||
<code>hotspot/test/native/</code> directory. Having all tests for a
|
||||
class in one file is a common practice for unit tests, it helps to see
|
||||
all existing tests at once, share functions and/or resources without
|
||||
losing encapsulation.</p></li>
|
||||
<li><p>For tests which test more than one class, directory hierarchy
|
||||
should be the same as product hierarchy, and file name should reflect
|
||||
the name of the tested subsystem/functionality. For example, if a
|
||||
sub-system under tests belongs to <code>gc/g1</code>, tests should be
|
||||
placed in <code>gc/g1</code> directory.</p></li>
|
||||
<li><p>All unit tests for a class from <code>foo/bar/baz.cpp</code> should be placed <code>foo/bar/test_baz.cpp</code> in <code>hotspot/test/native/</code> directory. Having all tests for a class in one file is a common practice for unit tests, it helps to see all existing tests at once, share functions and/or resources without losing encapsulation.</p></li>
|
||||
<li><p>For tests which test more than one class, directory hierarchy should be the same as product hierarchy, and file name should reflect the name of the tested subsystem/functionality. For example, if a sub-system under tests belongs to <code>gc/g1</code>, tests should be placed in <code>gc/g1</code> directory.</p></li>
|
||||
</ul>
|
||||
<p>Please note that framework prepends directory name to a test group
|
||||
name. For example, if <code>TEST(foo, check_this)</code> and
|
||||
<code>TEST(bar, check_that)</code> are defined in
|
||||
<code>hotspot/test/native/gc/shared/test_foo.cpp</code> file, they will
|
||||
be reported as <code>gc/shared/foo::check_this</code> and
|
||||
<code>gc/shared/bar::check_that</code>.</p>
|
||||
<p>Please note that framework prepends directory name to a test group name. For example, if <code>TEST(foo, check_this)</code> and <code>TEST(bar, check_that)</code> are defined in <code>hotspot/test/native/gc/shared/test_foo.cpp</code> file, they will be reported as <code>gc/shared/foo::check_this</code> and <code>gc/shared/bar::check_that</code>.</p>
|
||||
<h3 id="test-names">Test names</h3>
|
||||
<p>Test names should be in small_snake_case, start and end with a
|
||||
letter. A test name should reflect that a test checks.</p>
|
||||
<p>Such naming makes tests self-descriptive and helps a lot during the
|
||||
whole test life cycle. It is easy to do test planning, test inventory,
|
||||
to see what things are not tested, to review tests, to analyze test
|
||||
failures, to evolve a test, etc. For example
|
||||
<code>foo_return_0_if_name_is_null</code> is better than
|
||||
<code>foo_sanity</code> or <code>foo_basic</code> or just
|
||||
<code>foo</code>,
|
||||
<code>humongous_objects_can_not_be_moved_by_young_gc</code> is better
|
||||
than <code>ho_young_gc</code>.</p>
|
||||
<p>Actually using underscore is against GoogleTest project convention,
|
||||
because it can lead to illegal identifiers, however, this is too strict.
|
||||
Restricting usage of underscore for test names only and prohibiting test
|
||||
name starts or ends with an underscore are enough to be safe.</p>
|
||||
<p>Test names should be in small_snake_case, start and end with a letter. A test name should reflect that a test checks.</p>
|
||||
<p>Such naming makes tests self-descriptive and helps a lot during the whole test life cycle. It is easy to do test planning, test inventory, to see what things are not tested, to review tests, to analyze test failures, to evolve a test, etc. For example <code>foo_return_0_if_name_is_null</code> is better than <code>foo_sanity</code> or <code>foo_basic</code> or just <code>foo</code>, <code>humongous_objects_can_not_be_moved_by_young_gc</code> is better than <code>ho_young_gc</code>.</p>
|
||||
<p>Actually using underscore is against GoogleTest project convention, because it can lead to illegal identifiers, however, this is too strict. Restricting usage of underscore for test names only and prohibiting test name starts or ends with an underscore are enough to be safe.</p>
|
||||
<h3 id="fixture-classes">Fixture classes</h3>
|
||||
<p>Fixture classes should be named after tested classes, subsystems, etc
|
||||
(follow <a href="#test-group-names">Test group names rule</a>) and have
|
||||
<code>Test</code> suffix to prevent class name conflicts.</p>
|
||||
<p>Fixture classes should be named after tested classes, subsystems, etc (follow <a href="#test-group-names">Test group names rule</a>) and have <code>Test</code> suffix to prevent class name conflicts.</p>
|
||||
<h3 id="friend-classes">Friend classes</h3>
|
||||
<p>All test purpose friends should have either <code>Test</code> or
|
||||
<code>Testable</code> suffix.</p>
|
||||
<p>It greatly simplifies understanding of friendship’s purpose and
|
||||
allows statically check that private members are not exposed
|
||||
unexpectedly. Having <code>FooTest</code> as a friend of
|
||||
<code>Foo</code> without any comments will be understood as a necessary
|
||||
evil to get testability.</p>
|
||||
<p>All test purpose friends should have either <code>Test</code> or <code>Testable</code> suffix.</p>
|
||||
<p>It greatly simplifies understanding of friendship’s purpose and allows statically check that private members are not exposed unexpectedly. Having <code>FooTest</code> as a friend of <code>Foo</code> without any comments will be understood as a necessary evil to get testability.</p>
|
||||
<h3 id="oscpu-specific-tests">OS/CPU specific tests</h3>
|
||||
<p>Guard OS/CPU specific tests by <code>#ifdef</code> and have OS/CPU
|
||||
name in filename.</p>
|
||||
<p>For the time being, we do not support separate directories for OS,
|
||||
CPU, OS-CPU specific tests, in case we will have lots of such tests, we
|
||||
will change directory layout and build system to support that in the
|
||||
same way it is done in hotspot.</p>
|
||||
<p>Guard OS/CPU specific tests by <code>#ifdef</code> and have OS/CPU name in filename.</p>
|
||||
<p>For the time being, we do not support separate directories for OS, CPU, OS-CPU specific tests, in case we will have lots of such tests, we will change directory layout and build system to support that in the same way it is done in hotspot.</p>
|
||||
<h2 id="miscellaneous">Miscellaneous</h2>
|
||||
<h3 id="hotspot-style">Hotspot style</h3>
|
||||
<p>Abide the norms and rules accepted in Hotspot style guide.</p>
|
||||
<p>Tests are a part of Hotspot, so everything (if applicable) we use for
|
||||
Hotspot, should be used for tests as well. Those guidelines cover
|
||||
test-specific things.</p>
|
||||
<p>Tests are a part of Hotspot, so everything (if applicable) we use for Hotspot, should be used for tests as well. Those guidelines cover test-specific things.</p>
|
||||
<h3 id="codetest-metrics">Code/test metrics</h3>
|
||||
<p>Coverage information and other code/test metrics are quite useful to
|
||||
decide what tests should be written, what tests should be improved and
|
||||
what can be removed.</p>
|
||||
<p>For unit tests, widely used and well-known coverage metric is branch
|
||||
coverage, which provides good quality of tests with relatively easy test
|
||||
development process. For other levels of testing, branch coverage is not
|
||||
as good, and one should consider others metrics, e.g. transaction flow
|
||||
coverage, data flow coverage.</p>
|
||||
<p>Coverage information and other code/test metrics are quite useful to decide what tests should be written, what tests should be improved and what can be removed.</p>
|
||||
<p>For unit tests, widely used and well-known coverage metric is branch coverage, which provides good quality of tests with relatively easy test development process. For other levels of testing, branch coverage is not as good, and one should consider others metrics, e.g. transaction flow coverage, data flow coverage.</p>
|
||||
<h3 id="access-to-non-public-members">Access to non-public members</h3>
|
||||
<p>Use explicit friend class to get access to non-public members.</p>
|
||||
<p>We do not use GoogleTest macro to declare friendship relation,
|
||||
because, from our point of view, it is less clear than an explicit
|
||||
declaration.</p>
|
||||
<p>Declaring a test fixture class as a friend class of a tested test is
|
||||
the easiest and the clearest way to get access. However, it has some
|
||||
disadvantages, here is some of them:</p>
|
||||
<p>We do not use GoogleTest macro to declare friendship relation, because, from our point of view, it is less clear than an explicit declaration.</p>
|
||||
<p>Declaring a test fixture class as a friend class of a tested test is the easiest and the clearest way to get access. However, it has some disadvantages, here is some of them:</p>
|
||||
<ul>
|
||||
<li>Each test has to be declared as a friend</li>
|
||||
<li>Subclasses do not inheritance friendship relation</li>
|
||||
</ul>
|
||||
<p>In other words, it is harder to share code between tests. Hence if
|
||||
you want to share code or expect it to be useful in other tests, you
|
||||
should consider making members in a tested class protected and introduce
|
||||
a shared test-only class which expose those members via public
|
||||
functions, or even making members publicly accessible right away in a
|
||||
product class. If it is not an option to change members visibility, one
|
||||
can create a friend class which exposes members.</p>
|
||||
<p>In other words, it is harder to share code between tests. Hence if you want to share code or expect it to be useful in other tests, you should consider making members in a tested class protected and introduce a shared test-only class which expose those members via public functions, or even making members publicly accessible right away in a product class. If it is not an option to change members visibility, one can create a friend class which exposes members.</p>
|
||||
<h3 id="death-tests">Death tests</h3>
|
||||
<p>You can not use death tests inside <code>TEST_OTHER_VM</code> and
|
||||
<code>TEST_VM_ASSERT*</code>.</p>
|
||||
<p>We tried to make Hotspot-GoogleTest integration as transparent as
|
||||
possible, however, due to the current implementation of
|
||||
<code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code> tests, you
|
||||
cannot use death test functionality in them. These tests are implemented
|
||||
as GoogleTest death tests, and GoogleTest does not allow to have a death
|
||||
test inside another death test.</p>
|
||||
<p>You can not use death tests inside <code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code>.</p>
|
||||
<p>We tried to make Hotspot-GoogleTest integration as transparent as possible, however, due to the current implementation of <code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code> tests, you cannot use death test functionality in them. These tests are implemented as GoogleTest death tests, and GoogleTest does not allow to have a death test inside another death test.</p>
|
||||
<h3 id="external-flags">External flags</h3>
|
||||
<p>Passing external flags to a tested JVM is not supported.</p>
|
||||
<p>The rationality of such design decision is to simplify both tests and
|
||||
a test framework and to avoid failures related to incompatible flags
|
||||
combination till there is a good solution for that. However there are
|
||||
cases when one wants to test a JVM with specific flags combination,
|
||||
<code>_JAVA_OPTIONS</code> environment variable can be used to do that.
|
||||
Flags from <code>_JAVA_OPTIONS</code> will be used in
|
||||
<code>TEST_VM</code>, <code>TEST_OTHER_VM</code> and
|
||||
<code>TEST_VM_ASSERT*</code> tests.</p>
|
||||
<p>The rationality of such design decision is to simplify both tests and a test framework and to avoid failures related to incompatible flags combination till there is a good solution for that. However there are cases when one wants to test a JVM with specific flags combination, <code>_JAVA_OPTIONS</code> environment variable can be used to do that. Flags from <code>_JAVA_OPTIONS</code> will be used in <code>TEST_VM</code>, <code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code> tests.</p>
|
||||
<h3 id="test-specific-flags">Test-specific flags</h3>
|
||||
<p>Passing flags to a tested JVM in <code>TEST_OTHER_VM</code> and
|
||||
<code>TEST_VM_ASSERT*</code> should be possible, but is not implemented
|
||||
yet.</p>
|
||||
<p>Facility to pass test-specific flags is needed for system, regression
|
||||
or other types of tests which require a fully initialized JVM in some
|
||||
particular configuration, e.g. with Serial GC selected. There is no
|
||||
support for such tests now, however, there is a plan to add that in
|
||||
upcoming releases.</p>
|
||||
<p>For now, if a test depends on flags values, it should have
|
||||
<code>if (!<flag>) { return }</code> guards in the very beginning
|
||||
and <code>@requires</code> comment similar to jtreg
|
||||
<code>@requires</code> directive right before test macros. <a
|
||||
href="https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp"
|
||||
class="uri">https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp</a>
|
||||
ha an example of this temporary workaround. It is important to follow
|
||||
that pattern as it allows us to easily find all such tests and update
|
||||
them as soon as there is an implementation of flag passing facility.</p>
|
||||
<p>In long-term, we expect jtreg to support GoogleTest tests as first
|
||||
class citizens, that is to say, jtreg will parse <span class="citation"
|
||||
data-cites="requires">@requires</span> comments and filter out
|
||||
inapplicable tests.</p>
|
||||
<p>Passing flags to a tested JVM in <code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code> should be possible, but is not implemented yet.</p>
|
||||
<p>Facility to pass test-specific flags is needed for system, regression or other types of tests which require a fully initialized JVM in some particular configuration, e.g. with Serial GC selected. There is no support for such tests now, however, there is a plan to add that in upcoming releases.</p>
|
||||
<p>For now, if a test depends on flags values, it should have <code>if (!<flag>) { return }</code> guards in the very beginning and <code>@requires</code> comment similar to jtreg <code>@requires</code> directive right before test macros. <a href="https://hg.openjdk.java.net/jdk/jdk/file/tip/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp" class="uri">https://hg.openjdk.java.net/jdk/jdk/file/tip/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp</a> ha an example of this temporary workaround. It is important to follow that pattern as it allows us to easily find all such tests and update them as soon as there is an implementation of flag passing facility.</p>
|
||||
<p>In long-term, we expect jtreg to support GoogleTest tests as first class citizens, that is to say, jtreg will parse <span class="citation" data-cites="requires">@requires</span> comments and filter out inapplicable tests.</p>
|
||||
<h3 id="flag-restoring">Flag restoring</h3>
|
||||
<p>Restore changed flags.</p>
|
||||
<p>It is quite common for tests to configure JVM in a certain way
|
||||
changing flags’ values. GoogleTest provides two ways to set up
|
||||
environment before a test and restore it afterward: using either
|
||||
constructor and destructor or <code>SetUp</code> and
|
||||
<code>TearDown</code> functions. Both ways require to use a test fixture
|
||||
class, which sometimes is too wordy. The simpler facilities like
|
||||
<code>FLAG_GUARD</code> macro or <code>*FlagSetting</code> classes could
|
||||
be used in such cases to restore/set values.</p>
|
||||
<p>It is quite common for tests to configure JVM in a certain way changing flags’ values. GoogleTest provides two ways to set up environment before a test and restore it afterward: using either constructor and destructor or <code>SetUp</code> and <code>TearDown</code> functions. Both ways require to use a test fixture class, which sometimes is too wordy. The simpler facilities like <code>FLAG_GUARD</code> macro or <code>*FlagSetting</code> classes could be used in such cases to restore/set values.</p>
|
||||
<p>Caveats:</p>
|
||||
<ul>
|
||||
<li><p>Changing a flag’s value could break the invariants between flags'
|
||||
values and hence could lead to unexpected/unsupported JVM
|
||||
state.</p></li>
|
||||
<li><p><code>FLAG_SET_*</code> macros can change more than one flag (in
|
||||
order to maintain invariants) so it is hard to predict what flags will
|
||||
be changed and it makes restoring all changed flags a nontrivial task.
|
||||
Thus in case one uses <code>FLAG_SET_*</code> macros, they should use
|
||||
<code>TEST_OTHER_VM</code> test type.</p></li>
|
||||
<li><p>Changing a flag’s value could break the invariants between flags' values and hence could lead to unexpected/unsupported JVM state.</p></li>
|
||||
<li><p><code>FLAG_SET_*</code> macros can change more than one flag (in order to maintain invariants) so it is hard to predict what flags will be changed and it makes restoring all changed flags a nontrivial task. Thus in case one uses <code>FLAG_SET_*</code> macros, they should use <code>TEST_OTHER_VM</code> test type.</p></li>
|
||||
</ul>
|
||||
<h3 id="googletest-documentation">GoogleTest documentation</h3>
|
||||
<p>In case you have any questions regarding GoogleTest itself, its
|
||||
asserts, test declaration macros, other macros, etc, please consult its
|
||||
documentation.</p>
|
||||
<p>In case you have any questions regarding GoogleTest itself, its asserts, test declaration macros, other macros, etc, please consult its documentation.</p>
|
||||
<h2 id="todo">TODO</h2>
|
||||
<p>Although this document provides guidelines on the most important
|
||||
parts of test development using GTest, it still misses a few items:</p>
|
||||
<p>Although this document provides guidelines on the most important parts of test development using GTest, it still misses a few items:</p>
|
||||
<ul>
|
||||
<li><p>Examples, esp for <a href="#access-to-non-public-members">access
|
||||
to non-public members</a></p></li>
|
||||
<li><p>test types: purpose, drawbacks, limitation</p>
|
||||
<li><p>Examples, esp for <a href="#access-to-non-public-members">access to non-public members</a></p></li>
|
||||
<li>test types: purpose, drawbacks, limitation
|
||||
<ul>
|
||||
<li><code>TEST_VM</code></li>
|
||||
<li><code>TEST_VM_F</code></li>
|
||||
@@ -471,7 +195,7 @@ to non-public members</a></p></li>
|
||||
<li><code>TEST_VM_ASSERT</code></li>
|
||||
<li><code>TEST_VM_ASSERT_MSG</code></li>
|
||||
</ul></li>
|
||||
<li><p>Miscellaneous</p>
|
||||
<li>Miscellaneous
|
||||
<ul>
|
||||
<li>Test libraries
|
||||
<ul>
|
||||
@@ -484,8 +208,7 @@ to non-public members</a></p></li>
|
||||
<li>how to run tests in random order</li>
|
||||
<li>how to run only specific tests</li>
|
||||
<li>how to run each test separately</li>
|
||||
<li>check that a test can find bugs it is supposed to by introducing
|
||||
them</li>
|
||||
<li>check that a test can find bugs it is supposed to by introducing them</li>
|
||||
</ul></li>
|
||||
<li>mocks/stubs/dependency injection</li>
|
||||
<li>setUp/tearDown
|
||||
|
||||
@@ -100,7 +100,7 @@ Generally speaking to write a good test, one should create a model of
|
||||
the system under tests, a model of possible bugs (or bugs which one
|
||||
wants to find) and design tests using those models.
|
||||
|
||||
### Nearness
|
||||
### Nearness
|
||||
|
||||
Prefer having checks inside test code.
|
||||
|
||||
@@ -156,7 +156,7 @@ that the distance between compared values is not more than 4 ULPs,
|
||||
there is also `EXPECT_NEAR(v1, v2, eps)` which checks that the absolute
|
||||
value of the difference between `v1` and `v2` is not greater than `eps`.
|
||||
|
||||
### C string comparison
|
||||
### C string comparison
|
||||
|
||||
Use string special macros for C strings comparisons.
|
||||
|
||||
@@ -194,7 +194,7 @@ very bad practice. They just pollute output, so it becomes harder to
|
||||
find useful information. In order not print information till it is
|
||||
really needed, one should consider saving it to a temporary buffer and
|
||||
pass to an assert.
|
||||
<https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp>
|
||||
<https://hg.openjdk.java.net/jdk/jdk/file/tip/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp>
|
||||
has a good example how to do that.
|
||||
|
||||
### Failures propagation
|
||||
@@ -229,7 +229,7 @@ test failure analysis. For example, class `Foo` - test group `Foo`,
|
||||
compiler logging subsystem - test group `CompilerLogging`, G1 GC — test
|
||||
group `G1GC`, and so forth.
|
||||
|
||||
### Filename
|
||||
### Filename
|
||||
|
||||
A test file must have `test_` prefix and `.cpp` suffix.
|
||||
|
||||
@@ -283,7 +283,7 @@ Fixture classes should be named after tested classes, subsystems, etc
|
||||
(follow [Test group names rule](#test-group-names)) and have
|
||||
`Test` suffix to prevent class name conflicts.
|
||||
|
||||
### Friend classes
|
||||
### Friend classes
|
||||
|
||||
All test purpose friends should have either `Test` or `Testable` suffix.
|
||||
|
||||
@@ -303,7 +303,7 @@ the same way it is done in hotspot.
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
### Hotspot style
|
||||
### Hotspot style
|
||||
|
||||
Abide the norms and rules accepted in Hotspot style guide.
|
||||
|
||||
@@ -383,7 +383,7 @@ upcoming releases.
|
||||
For now, if a test depends on flags values, it should have `if
|
||||
(!<flag>) { return }` guards in the very beginning and `@requires`
|
||||
comment similar to jtreg `@requires` directive right before test macros.
|
||||
<https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp>
|
||||
<https://hg.openjdk.java.net/jdk/jdk/file/tip/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp>
|
||||
ha an example of this temporary workaround. It is important to follow
|
||||
that pattern as it allows us to easily find all such tests and update
|
||||
them as soon as there is an implementation of flag passing facility.
|
||||
@@ -392,7 +392,7 @@ In long-term, we expect jtreg to support GoogleTest tests as first
|
||||
class citizens, that is to say, jtreg will parse @requires comments
|
||||
and filter out inapplicable tests.
|
||||
|
||||
### Flag restoring
|
||||
### Flag restoring
|
||||
|
||||
Restore changed flags.
|
||||
|
||||
@@ -404,7 +404,7 @@ require to use a test fixture class, which sometimes is too wordy. The
|
||||
simpler facilities like `FLAG_GUARD` macro or `*FlagSetting` classes could
|
||||
be used in such cases to restore/set values.
|
||||
|
||||
Caveats:
|
||||
Caveats:
|
||||
|
||||
* Changing a flag’s value could break the invariants between flags' values and hence could lead to unexpected/unsupported JVM state.
|
||||
|
||||
|
||||
95
doc/ide.html
95
doc/ide.html
@@ -5,19 +5,11 @@
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>IDE support in the JDK</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
<style type="text/css">
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" />
|
||||
<!--[if lt IE 9]>
|
||||
@@ -28,82 +20,35 @@
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">IDE support in the JDK</h1>
|
||||
</header>
|
||||
<nav id="TOC" role="doc-toc">
|
||||
<nav id="TOC">
|
||||
<ul>
|
||||
<li><a href="#introduction" id="toc-introduction">Introduction</a>
|
||||
<ul>
|
||||
<li><a href="#ide-support-for-native-code"
|
||||
id="toc-ide-support-for-native-code">IDE support for native
|
||||
code</a></li>
|
||||
<li><a href="#ide-support-for-java-code"
|
||||
id="toc-ide-support-for-java-code">IDE support for Java code</a></li>
|
||||
<li><a href="#introduction">Introduction</a><ul>
|
||||
<li><a href="#ide-support-for-native-code">IDE support for native code</a></li>
|
||||
<li><a href="#ide-support-for-java-code">IDE support for Java code</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<h2 id="introduction">Introduction</h2>
|
||||
<p>When you are familiar with building and testing the JDK, you may want
|
||||
to configure an IDE to work with the source code. The instructions
|
||||
differ a bit depending on whether you are interested in working with the
|
||||
native (C/C++) or the Java code.</p>
|
||||
<p>When you are familiar with building and testing the JDK, you may want to configure an IDE to work with the source code. The instructions differ a bit depending on whether you are interested in working with the native (C/C++) or the Java code.</p>
|
||||
<h3 id="ide-support-for-native-code">IDE support for native code</h3>
|
||||
<p>There are a few ways to generate IDE configuration for the native
|
||||
sources, depending on which IDE to use.</p>
|
||||
<p>There are a few ways to generate IDE configuration for the native sources, depending on which IDE to use.</p>
|
||||
<h4 id="visual-studio-code">Visual Studio Code</h4>
|
||||
<p>The make system can generate a <a
|
||||
href="https://code.visualstudio.com">Visual Studio Code</a> workspace
|
||||
that has C/C++ source indexing configured correctly, as well as launcher
|
||||
targets for tests and the Java launcher. After configuring, a workspace
|
||||
for the configuration can be generated using:</p>
|
||||
<p>The make system can generate a <a href="https://code.visualstudio.com">Visual Studio Code</a> workspace that has C/C++ source indexing configured correctly, as well as launcher targets for tests and the Java launcher. After configuring, a workspace for the configuration can be generated using:</p>
|
||||
<pre class="shell"><code>make vscode-project</code></pre>
|
||||
<p>This creates a file called <code>jdk.code-workspace</code> in the
|
||||
build output folder. The full location will be printed after the
|
||||
workspace has been generated. To use it, choose
|
||||
<code>File -> Open Workspace...</code> in Visual Studio Code.</p>
|
||||
<p>This creates a file called <code>jdk.code-workspace</code> in the build output folder. The full location will be printed after the workspace has been generated. To use it, choose <code>File -> Open Workspace...</code> in Visual Studio Code.</p>
|
||||
<h5 id="alternative-indexers">Alternative indexers</h5>
|
||||
<p>The main <code>vscode-project</code> target configures the default
|
||||
C++ support in Visual Studio Code. There are also other source indexers
|
||||
that can be installed, that may provide additional features. It's
|
||||
currently possible to generate configuration for two such indexers, <a
|
||||
href="https://clang.llvm.org/extra/clangd/">clangd</a> and <a
|
||||
href="https://github.com/Andersbakken/rtags">rtags</a>. These can be
|
||||
configured by appending the name of the indexer to the make target, such
|
||||
as:</p>
|
||||
<p>The main <code>vscode-project</code> target configures the default C++ support in Visual Studio Code. There are also other source indexers that can be installed, that may provide additional features. It's currently possible to generate configuration for two such indexers, <a href="https://clang.llvm.org/extra/clangd/">clangd</a> and <a href="https://github.com/Andersbakken/rtags">rtags</a>. These can be configured by appending the name of the indexer to the make target, such as:</p>
|
||||
<pre class="shell"><code>make vscode-project-clangd</code></pre>
|
||||
<p>Additional instructions for configuring the given indexer will be
|
||||
displayed after the workspace has been generated.</p>
|
||||
<p>Additional instructions for configuring the given indexer will be displayed after the workspace has been generated.</p>
|
||||
<h4 id="visual-studio">Visual Studio</h4>
|
||||
<p>The make system can generate a Visual Studio project for the Hotspot
|
||||
native source. After configuring, the project is generated using:</p>
|
||||
<pre class="shell"><code>make hotspot-ide-project</code></pre>
|
||||
<p>This creates a file named <code>jvm.vcxproj</code> in
|
||||
<code>ide\hotspot-visualstudio</code> subfolder of the build output
|
||||
folder. The file can be opened in Visual Studio via
|
||||
<code>File -> Open -> Project/Solution</code>.</p>
|
||||
<p>This section is a work in progress.</p>
|
||||
<pre class="shell"><code>make ide-project</code></pre>
|
||||
<h4 id="compilation-database">Compilation Database</h4>
|
||||
<p>The make system can generate generic native code indexing support in
|
||||
the form of a <a
|
||||
href="https://clang.llvm.org/docs/JSONCompilationDatabase.html">Compilation
|
||||
Database</a> that can be used by many different IDEs and source code
|
||||
indexers.</p>
|
||||
<p>The make system can generate generic native code indexing support in the form of a <a href="https://clang.llvm.org/docs/JSONCompilationDatabase.html">Compilation Database</a> that can be used by many different IDEs and source code indexers.</p>
|
||||
<pre class="shell"><code>make compile-commands</code></pre>
|
||||
<p>It's also possible to generate the Compilation Database for the
|
||||
HotSpot source code only, which is a bit faster as it includes less
|
||||
information.</p>
|
||||
<p>It's also possible to generate the Compilation Database for the HotSpot source code only, which is a bit faster as it includes less information.</p>
|
||||
<pre class="shell"><code>make compile-commands-hotspot</code></pre>
|
||||
<h3 id="ide-support-for-java-code">IDE support for Java code</h3>
|
||||
<h4 id="intellij-idea">IntelliJ IDEA</h4>
|
||||
<p>The JDK project has a script that can be used for indexing the
|
||||
project with IntelliJ. After configuring and building the JDK, an
|
||||
IntelliJ workspace can be generated by running the following command in
|
||||
the top-level folder of the cloned repository:</p>
|
||||
<pre class="shell"><code>bash bin/idea.sh</code></pre>
|
||||
<p>To use it, choose <code>File -> Open...</code> in IntelliJ and
|
||||
select the folder where you ran the above script.</p>
|
||||
<p>Next, configure the project SDK in IntelliJ. Open
|
||||
<code>File -> Project Structure -> Project</code> and select
|
||||
<code>build/<config>/images/jdk</code> as the SDK to use.</p>
|
||||
<p>In order to run the tests from the IDE, you can use the JTReg plugin.
|
||||
Instructions for building and using the plugin can be found <a
|
||||
href="https://github.com/openjdk/jtreg/tree/master/plugins/idea">here</a>.</p>
|
||||
<p>This section is a work in progress.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
31
doc/ide.md
31
doc/ide.md
@@ -45,17 +45,12 @@ after the workspace has been generated.
|
||||
|
||||
#### Visual Studio
|
||||
|
||||
The make system can generate a Visual Studio project for the Hotspot
|
||||
native source. After configuring, the project is generated using:
|
||||
This section is a work in progress.
|
||||
|
||||
```shell
|
||||
make hotspot-ide-project
|
||||
make ide-project
|
||||
```
|
||||
|
||||
This creates a file named `jvm.vcxproj` in `ide\hotspot-visualstudio`
|
||||
subfolder of the build output folder. The file can be opened in Visual Studio
|
||||
via `File -> Open -> Project/Solution`.
|
||||
|
||||
#### Compilation Database
|
||||
|
||||
The make system can generate generic native code indexing support in the form of
|
||||
@@ -75,24 +70,4 @@ make compile-commands-hotspot
|
||||
|
||||
### IDE support for Java code
|
||||
|
||||
#### IntelliJ IDEA
|
||||
|
||||
The JDK project has a script that can be used for indexing the project
|
||||
with IntelliJ. After configuring and building the JDK, an IntelliJ workspace
|
||||
can be generated by running the following command in the top-level folder
|
||||
of the cloned repository:
|
||||
|
||||
```shell
|
||||
bash bin/idea.sh
|
||||
```
|
||||
|
||||
To use it, choose `File -> Open...` in IntelliJ and select the folder where
|
||||
you ran the above script.
|
||||
|
||||
Next, configure the project SDK in IntelliJ. Open
|
||||
`File -> Project Structure -> Project` and select `build/<config>/images/jdk`
|
||||
as the SDK to use.
|
||||
|
||||
In order to run the tests from the IDE, you can use the JTReg plugin.
|
||||
Instructions for building and using the plugin can be found
|
||||
[here](https://github.com/openjdk/jtreg/tree/master/plugins/idea).
|
||||
This section is a work in progress.
|
||||
592
doc/testing.html
592
doc/testing.html
@@ -5,99 +5,53 @@
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>Testing the JDK</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
<style type="text/css">
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" />
|
||||
<style type="text/css">pre, code, tt { color: #1d6ae5; }</style>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||
<![endif]-->
|
||||
<style type="text/css">pre, code, tt { color: #1d6ae5; }</style>
|
||||
</head>
|
||||
<body>
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">Testing the JDK</h1>
|
||||
</header>
|
||||
<nav id="TOC" role="doc-toc">
|
||||
<nav id="TOC">
|
||||
<ul>
|
||||
<li><a href="#overview" id="toc-overview">Overview</a></li>
|
||||
<li><a href="#running-tests-locally-with-make-test"
|
||||
id="toc-running-tests-locally-with-make-test">Running tests locally with
|
||||
<code>make test</code></a>
|
||||
<ul>
|
||||
<li><a href="#configuration"
|
||||
id="toc-configuration">Configuration</a></li>
|
||||
<li><a href="#using-make-test-the-run-test-framework">Using "make test" (the run-test framework)</a><ul>
|
||||
<li><a href="#configuration">Configuration</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#test-selection" id="toc-test-selection">Test selection</a>
|
||||
<ul>
|
||||
<li><a href="#common-test-groups" id="toc-common-test-groups">Common
|
||||
Test Groups</a></li>
|
||||
<li><a href="#jtreg" id="toc-jtreg">JTReg</a></li>
|
||||
<li><a href="#gtest" id="toc-gtest">Gtest</a></li>
|
||||
<li><a href="#microbenchmarks"
|
||||
id="toc-microbenchmarks">Microbenchmarks</a></li>
|
||||
<li><a href="#special-tests" id="toc-special-tests">Special
|
||||
tests</a></li>
|
||||
<li><a href="#test-selection">Test selection</a><ul>
|
||||
<li><a href="#common-test-groups">Common Test Groups</a></li>
|
||||
<li><a href="#jtreg">JTReg</a></li>
|
||||
<li><a href="#gtest">Gtest</a></li>
|
||||
<li><a href="#microbenchmarks">Microbenchmarks</a></li>
|
||||
<li><a href="#special-tests">Special tests</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#test-results-and-summary"
|
||||
id="toc-test-results-and-summary">Test results and summary</a></li>
|
||||
<li><a href="#test-suite-control" id="toc-test-suite-control">Test suite
|
||||
control</a>
|
||||
<ul>
|
||||
<li><a href="#general-keywords-test_opts"
|
||||
id="toc-general-keywords-test_opts">General keywords
|
||||
(TEST_OPTS)</a></li>
|
||||
<li><a href="#jtreg-keywords" id="toc-jtreg-keywords">JTReg
|
||||
keywords</a></li>
|
||||
<li><a href="#gtest-keywords" id="toc-gtest-keywords">Gtest
|
||||
keywords</a></li>
|
||||
<li><a href="#microbenchmark-keywords"
|
||||
id="toc-microbenchmark-keywords">Microbenchmark keywords</a></li>
|
||||
<li><a href="#test-results-and-summary">Test results and summary</a></li>
|
||||
<li><a href="#test-suite-control">Test suite control</a><ul>
|
||||
<li><a href="#general-keywords-test_opts">General keywords (TEST_OPTS)</a></li>
|
||||
<li><a href="#jtreg-keywords">JTReg keywords</a></li>
|
||||
<li><a href="#gtest-keywords">Gtest keywords</a></li>
|
||||
<li><a href="#microbenchmark-keywords">Microbenchmark keywords</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#notes-for-specific-tests"
|
||||
id="toc-notes-for-specific-tests">Notes for Specific Tests</a>
|
||||
<ul>
|
||||
<li><a href="#docker-tests" id="toc-docker-tests">Docker Tests</a></li>
|
||||
<li><a href="#non-us-locale" id="toc-non-us-locale">Non-US
|
||||
locale</a></li>
|
||||
<li><a href="#pkcs11-tests" id="toc-pkcs11-tests">PKCS11 Tests</a></li>
|
||||
<li><a href="#client-ui-tests" id="toc-client-ui-tests">Client UI
|
||||
Tests</a></li>
|
||||
<li><a href="#notes-for-specific-tests">Notes for Specific Tests</a><ul>
|
||||
<li><a href="#docker-tests">Docker Tests</a></li>
|
||||
<li><a href="#non-us-locale">Non-US locale</a></li>
|
||||
<li><a href="#pkcs11-tests">PKCS11 Tests</a></li>
|
||||
<li><a href="#client-ui-tests">Client UI Tests</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#editing-this-document"
|
||||
id="toc-editing-this-document">Editing this document</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<h2 id="overview">Overview</h2>
|
||||
<p>The bulk of JDK tests use <a
|
||||
href="https://openjdk.org/jtreg/">jtreg</a>, a regression test framework
|
||||
and test runner built for the JDK's specific needs. Other test
|
||||
frameworks are also used. The different test frameworks can be executed
|
||||
directly, but there is also a set of make targets intended to simplify
|
||||
the interface, and figure out how to run your tests for you.</p>
|
||||
<h2 id="running-tests-locally-with-make-test">Running tests locally with
|
||||
<code>make test</code></h2>
|
||||
<p>This is the easiest way to get started. Assuming you've built the JDK
|
||||
locally, execute:</p>
|
||||
<pre><code>$ make test</code></pre>
|
||||
<p>This will run a default set of tests against the JDK, and present you
|
||||
with the results. <code>make test</code> is part of a family of
|
||||
test-related make targets which simplify running tests, because they
|
||||
invoke the various test frameworks for you. The "make test framework" is
|
||||
simple to start with, but more complex ad-hoc combination of tests is
|
||||
also possible. You can always invoke the test frameworks directly if you
|
||||
want even more control.</p>
|
||||
<h2 id="using-make-test-the-run-test-framework">Using "make test" (the run-test framework)</h2>
|
||||
<p>This new way of running tests is developer-centric. It assumes that you have built a JDK locally and want to test it. Running common test targets is simple, and more complex ad-hoc combination of tests is possible. The user interface is forgiving, and clearly report errors it cannot resolve.</p>
|
||||
<p>The main target <code>test</code> uses the jdk-image as the tested product. There is also an alternate target <code>exploded-test</code> that uses the exploded image instead. Not all tests will run successfully on the exploded image, but using this target can greatly improve rebuild times for certain workflows.</p>
|
||||
<p>Previously, <code>make test</code> was used to invoke an old system for running tests, and <code>make run-test</code> was used for the new test framework. For backward compatibility with scripts and muscle memory, <code>run-test</code> (and variants like <code>exploded-run-test</code> or <code>run-test-tier1</code>) are kept as aliases.</p>
|
||||
<p>Some example command-lines:</p>
|
||||
<pre><code>$ make test-tier1
|
||||
$ make test-jdk_lang JTREG="JOBS=8"
|
||||
@@ -107,214 +61,48 @@ $ make test TEST="hotspot:hotspot_gc" JTREG="JOBS=1;TIMEOUT_FACTO
|
||||
$ make test TEST="jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java"
|
||||
$ make test TEST="micro:java.lang.reflect" MICRO="FORK=1;WARMUP_ITER=2"
|
||||
$ make exploded-test TEST=tier2</code></pre>
|
||||
<p>"tier1" and "tier2" refer to tiered testing, see further down. "TEST"
|
||||
is a test selection argument which the make test framework will use to
|
||||
try to find the tests you want. It iterates over the available test
|
||||
frameworks, and if the test isn't present in one, it tries the next one.
|
||||
The main target <code>test</code> uses the jdk-image as the tested
|
||||
product. There is also an alternate target <code>exploded-test</code>
|
||||
that uses the exploded image instead. Not all tests will run
|
||||
successfully on the exploded image, but using this target can greatly
|
||||
improve rebuild times for certain workflows.</p>
|
||||
<p>Previously, <code>make test</code> was used to invoke an old system
|
||||
for running tests, and <code>make run-test</code> was used for the new
|
||||
test framework. For backward compatibility with scripts and muscle
|
||||
memory, <code>run-test</code> and variants like
|
||||
<code>exploded-run-test</code> or <code>run-test-tier1</code> are kept
|
||||
as aliases.</p>
|
||||
<h3 id="configuration">Configuration</h3>
|
||||
<p>To be able to run JTReg tests, <code>configure</code> needs to know
|
||||
where to find the JTReg test framework. If it is not picked up
|
||||
automatically by configure, use the
|
||||
<code>--with-jtreg=<path to jtreg home></code> option to point to
|
||||
the JTReg framework. Note that this option should point to the JTReg
|
||||
home, i.e. the top directory, containing <code>lib/jtreg.jar</code> etc.
|
||||
(An alternative is to set the <code>JT_HOME</code> environment variable
|
||||
to point to the JTReg home before running <code>configure</code>.)</p>
|
||||
<p>To be able to run microbenchmarks, <code>configure</code> needs to
|
||||
know where to find the JMH dependency. Use
|
||||
<code>--with-jmh=<path to JMH jars></code> to point to a directory
|
||||
containing the core JMH and transitive dependencies. The recommended
|
||||
dependencies can be retrieved by running
|
||||
<code>sh make/devkit/createJMHBundle.sh</code>, after which
|
||||
<code>--with-jmh=build/jmh/jars</code> should work.</p>
|
||||
<p>When tests fail or timeout, jtreg runs its failure handler to capture
|
||||
necessary data from the system where the test was run. This data can
|
||||
then be used to analyze the test failures. Collecting this data involves
|
||||
running various commands (which are listed in files residing in
|
||||
<code>test/failure_handler/src/share/conf</code>) and some of these
|
||||
commands use <code>sudo</code>. If the system's <code>sudoers</code>
|
||||
file isn't configured to allow running these commands, then it can
|
||||
result in password being prompted during the failure handler execution.
|
||||
Typically, when running locally, collecting this additional data isn't
|
||||
always necessary. To disable running the failure handler, use
|
||||
<code>--enable-jtreg-failure-handler=no</code> when running
|
||||
<code>configure</code>. If, however, you want to let the failure handler
|
||||
to run and don't want to be prompted for sudo password, then you can
|
||||
configure your <code>sudoers</code> file appropriately. Please read the
|
||||
necessary documentation of your operating system to see how to do that;
|
||||
here we only show one possible way of doing that - edit the
|
||||
<code>/etc/sudoers.d/sudoers</code> file to include the following
|
||||
line:</p>
|
||||
<pre><code>johndoe ALL=(ALL) NOPASSWD: /sbin/dmesg</code></pre>
|
||||
<p>This line configures <code>sudo</code> to <em>not</em> prompt for
|
||||
password for the <code>/sbin/dmesg</code> command (this is one of the
|
||||
commands that is listed in the files at
|
||||
<code>test/failure_handler/src/share/conf</code>), for the user
|
||||
<code>johndoe</code>. Here <code>johndoe</code> is the user account
|
||||
under which the jtreg tests are run. Replace the username with a
|
||||
relevant user account of your system.</p>
|
||||
<p>To be able to run JTReg tests, <code>configure</code> needs to know where to find the JTReg test framework. If it is not picked up automatically by configure, use the <code>--with-jtreg=<path to jtreg home></code> option to point to the JTReg framework. Note that this option should point to the JTReg home, i.e. the top directory, containing <code>lib/jtreg.jar</code> etc. (An alternative is to set the <code>JT_HOME</code> environment variable to point to the JTReg home before running <code>configure</code>.)</p>
|
||||
<p>To be able to run microbenchmarks, <code>configure</code> needs to know where to find the JMH dependency. Use <code>--with-jmh=<path to JMH jars></code> to point to a directory containing the core JMH and transitive dependencies. The recommended dependencies can be retrieved by running <code>sh make/devkit/createJMHBundle.sh</code>, after which <code>--with-jmh=build/jmh/jars</code> should work.</p>
|
||||
<h2 id="test-selection">Test selection</h2>
|
||||
<p>All functionality is available using the <code>test</code> make
|
||||
target. In this use case, the test or tests to be executed is controlled
|
||||
using the <code>TEST</code> variable. To speed up subsequent test runs
|
||||
with no source code changes, <code>test-only</code> can be used instead,
|
||||
which do not depend on the source and test image build.</p>
|
||||
<p>For some common top-level tests, direct make targets have been
|
||||
generated. This includes all JTReg test groups, the hotspot gtest, and
|
||||
custom tests (if present). This means that <code>make test-tier1</code>
|
||||
is equivalent to <code>make test TEST="tier1"</code>, but the latter is
|
||||
more tab-completion friendly. For more complex test runs, the
|
||||
<code>test TEST="x"</code> solution needs to be used.</p>
|
||||
<p>The test specifications given in <code>TEST</code> is parsed into
|
||||
fully qualified test descriptors, which clearly and unambigously show
|
||||
which tests will be run. As an example, <code>:tier1</code> will expand
|
||||
to
|
||||
<code>jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1</code>.
|
||||
You can always submit a list of fully qualified test descriptors in the
|
||||
<code>TEST</code> variable if you want to shortcut the parser.</p>
|
||||
<p>All functionality is available using the <code>test</code> make target. In this use case, the test or tests to be executed is controlled using the <code>TEST</code> variable. To speed up subsequent test runs with no source code changes, <code>test-only</code> can be used instead, which do not depend on the source and test image build.</p>
|
||||
<p>For some common top-level tests, direct make targets have been generated. This includes all JTReg test groups, the hotspot gtest, and custom tests (if present). This means that <code>make test-tier1</code> is equivalent to <code>make test TEST="tier1"</code>, but the latter is more tab-completion friendly. For more complex test runs, the <code>test TEST="x"</code> solution needs to be used.</p>
|
||||
<p>The test specifications given in <code>TEST</code> is parsed into fully qualified test descriptors, which clearly and unambigously show which tests will be run. As an example, <code>:tier1</code> will expand to <code>jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1</code>. You can always submit a list of fully qualified test descriptors in the <code>TEST</code> variable if you want to shortcut the parser.</p>
|
||||
<h3 id="common-test-groups">Common Test Groups</h3>
|
||||
<p>Ideally, all tests are run for every change but this may not be
|
||||
practical due to the limited testing resources, the scope of the change,
|
||||
etc.</p>
|
||||
<p>The source tree currently defines a few common test groups in the
|
||||
relevant <code>TEST.groups</code> files. There are test groups that
|
||||
cover a specific component, for example <code>hotspot_gc</code>. It is a
|
||||
good idea to look into <code>TEST.groups</code> files to get a sense
|
||||
what tests are relevant to a particular JDK component.</p>
|
||||
<p>Component-specific tests may miss some unintended consequences of a
|
||||
change, so other tests should also be run. Again, it might be
|
||||
impractical to run all tests, and therefore <em>tiered</em> test groups
|
||||
exist. Tiered test groups are not component-specific, but rather cover
|
||||
the significant parts of the entire JDK.</p>
|
||||
<p>Multiple tiers allow balancing test coverage and testing costs. Lower
|
||||
test tiers are supposed to contain the simpler, quicker and more stable
|
||||
tests. Higher tiers are supposed to contain progressively more thorough,
|
||||
slower, and sometimes less stable tests, or the tests that require
|
||||
special configuration.</p>
|
||||
<p>Contributors are expected to run the tests for the areas that are
|
||||
changed, and the first N tiers they can afford to run, but at least
|
||||
tier1.</p>
|
||||
<p>Ideally, all tests are run for every change but this may not be practical due to the limited testing resources, the scope of the change, etc.</p>
|
||||
<p>The source tree currently defines a few common test groups in the relevant <code>TEST.groups</code> files. There are test groups that cover a specific component, for example <code>hotspot_gc</code>. It is a good idea to look into <code>TEST.groups</code> files to get a sense what tests are relevant to a particular JDK component.</p>
|
||||
<p>Component-specific tests may miss some unintended consequences of a change, so other tests should also be run. Again, it might be impractical to run all tests, and therefore <em>tiered</em> test groups exist. Tiered test groups are not component-specific, but rather cover the significant parts of the entire JDK.</p>
|
||||
<p>Multiple tiers allow balancing test coverage and testing costs. Lower test tiers are supposed to contain the simpler, quicker and more stable tests. Higher tiers are supposed to contain progressively more thorough, slower, and sometimes less stable tests, or the tests that require special configuration.</p>
|
||||
<p>Contributors are expected to run the tests for the areas that are changed, and the first N tiers they can afford to run, but at least tier1.</p>
|
||||
<p>A brief description of the tiered test groups:</p>
|
||||
<ul>
|
||||
<li><p><code>tier1</code>: This is the lowest test tier. Multiple
|
||||
developers run these tests every day. Because of the widespread use, the
|
||||
tests in <code>tier1</code> are carefully selected and optimized to run
|
||||
fast, and to run in the most stable manner. The test failures in
|
||||
<code>tier1</code> are usually followed up on quickly, either with
|
||||
fixes, or adding relevant tests to problem list. GitHub Actions
|
||||
workflows, if enabled, run <code>tier1</code> tests.</p></li>
|
||||
<li><p><code>tier2</code>: This test group covers even more ground.
|
||||
These contain, among other things, tests that either run for too long to
|
||||
be at <code>tier1</code>, or may require special configuration, or tests
|
||||
that are less stable, or cover the broader range of non-core JVM and JDK
|
||||
features/components(for example, XML).</p></li>
|
||||
<li><p><code>tier3</code>: This test group includes more stressful
|
||||
tests, the tests for corner cases not covered by previous tiers, plus
|
||||
the tests that require GUIs. As such, this suite should either be run
|
||||
with low concurrency (<code>TEST_JOBS=1</code>), or without headful
|
||||
tests(<code>JTREG_KEYWORDS=\!headful</code>), or both.</p></li>
|
||||
<li><p><code>tier4</code>: This test group includes every other test not
|
||||
covered by previous tiers. It includes, for example,
|
||||
<code>vmTestbase</code> suites for Hotspot, which run for many hours
|
||||
even on large machines. It also runs GUI tests, so the same
|
||||
<code>TEST_JOBS</code> and <code>JTREG_KEYWORDS</code> caveats
|
||||
apply.</p></li>
|
||||
<li><p><code>tier1</code>: This is the lowest test tier. Multiple developers run these tests every day. Because of the widespread use, the tests in <code>tier1</code> are carefully selected and optimized to run fast, and to run in the most stable manner. The test failures in <code>tier1</code> are usually followed up on quickly, either with fixes, or adding relevant tests to problem list. GitHub Actions workflows, if enabled, run <code>tier1</code> tests.</p></li>
|
||||
<li><p><code>tier2</code>: This test group covers even more ground. These contain, among other things, tests that either run for too long to be at <code>tier1</code>, or may require special configuration, or tests that are less stable, or cover the broader range of non-core JVM and JDK features/components (for example, XML).</p></li>
|
||||
<li><p><code>tier3</code>: This test group includes more stressful tests, the tests for corner cases not covered by previous tiers, plus the tests that require GUIs. As such, this suite should either be run with low concurrency (<code>TEST_JOBS=1</code>), or without headful tests (<code>JTREG_KEYWORDS=\!headful</code>), or both.</p></li>
|
||||
<li><p><code>tier4</code>: This test group includes every other test not covered by previous tiers. It includes, for example, <code>vmTestbase</code> suites for Hotspot, which run for many hours even on large machines. It also runs GUI tests, so the same <code>TEST_JOBS</code> and <code>JTREG_KEYWORDS</code> caveats apply.</p></li>
|
||||
</ul>
|
||||
<h3 id="jtreg">JTReg</h3>
|
||||
<p>JTReg tests can be selected either by picking a JTReg test group, or
|
||||
a selection of files or directories containing JTReg tests.
|
||||
Documentation can be found at <a
|
||||
href="https://openjdk.org/jtreg/">https://openjdk.org/jtreg/</a>, note
|
||||
especially the extensive <a
|
||||
href="https://openjdk.org/jtreg/faq.html">FAQ</a>.</p>
|
||||
<p>JTReg test groups can be specified either without a test root, e.g.
|
||||
<code>:tier1</code> (or <code>tier1</code>, the initial colon is
|
||||
optional), or with, e.g. <code>hotspot:tier1</code>,
|
||||
<code>test/jdk:jdk_util</code> or
|
||||
<code>$(TOPDIR)/test/hotspot/jtreg:hotspot_all</code>. The test root can
|
||||
be specified either as an absolute path, or a path relative to the JDK
|
||||
top directory, or the <code>test</code> directory. For simplicity, the
|
||||
hotspot JTReg test root, which really is <code>hotspot/jtreg</code> can
|
||||
be abbreviated as just <code>hotspot</code>.</p>
|
||||
<p>When specified without a test root, all matching groups from all test
|
||||
roots will be added. Otherwise, only the group from the specified test
|
||||
root will be added.</p>
|
||||
<p>Individual JTReg tests or directories containing JTReg tests can also
|
||||
be specified, like
|
||||
<code>test/hotspot/jtreg/native_sanity/JniVersion.java</code> or
|
||||
<code>hotspot/jtreg/native_sanity</code>. Just like for test root
|
||||
selection, you can either specify an absolute path (which can even point
|
||||
to JTReg tests outside the source tree), or a path relative to either
|
||||
the JDK top directory or the <code>test</code> directory.
|
||||
<code>hotspot</code> can be used as an alias for
|
||||
<code>hotspot/jtreg</code> here as well.</p>
|
||||
<p>As long as the test groups or test paths can be uniquely resolved,
|
||||
you do not need to enter the <code>jtreg:</code> prefix. If this is not
|
||||
possible, or if you want to use a fully qualified test descriptor, add
|
||||
<code>jtreg:</code>, e.g.
|
||||
<code>jtreg:test/hotspot/jtreg/native_sanity</code>.</p>
|
||||
<p>JTReg tests can be selected either by picking a JTReg test group, or a selection of files or directories containing JTReg tests.</p>
|
||||
<p>JTReg test groups can be specified either without a test root, e.g. <code>:tier1</code> (or <code>tier1</code>, the initial colon is optional), or with, e.g. <code>hotspot:tier1</code>, <code>test/jdk:jdk_util</code> or <code>$(TOPDIR)/test/hotspot/jtreg:hotspot_all</code>. The test root can be specified either as an absolute path, or a path relative to the JDK top directory, or the <code>test</code> directory. For simplicity, the hotspot JTReg test root, which really is <code>hotspot/jtreg</code> can be abbreviated as just <code>hotspot</code>.</p>
|
||||
<p>When specified without a test root, all matching groups from all test roots will be added. Otherwise, only the group from the specified test root will be added.</p>
|
||||
<p>Individual JTReg tests or directories containing JTReg tests can also be specified, like <code>test/hotspot/jtreg/native_sanity/JniVersion.java</code> or <code>hotspot/jtreg/native_sanity</code>. Just like for test root selection, you can either specify an absolute path (which can even point to JTReg tests outside the source tree), or a path relative to either the JDK top directory or the <code>test</code> directory. <code>hotspot</code> can be used as an alias for <code>hotspot/jtreg</code> here as well.</p>
|
||||
<p>As long as the test groups or test paths can be uniquely resolved, you do not need to enter the <code>jtreg:</code> prefix. If this is not possible, or if you want to use a fully qualified test descriptor, add <code>jtreg:</code>, e.g. <code>jtreg:test/hotspot/jtreg/native_sanity</code>.</p>
|
||||
<h3 id="gtest">Gtest</h3>
|
||||
<p><strong>Note:</strong> To be able to run the Gtest suite, you need to
|
||||
configure your build to be able to find a proper version of the gtest
|
||||
source. For details, see the section <a
|
||||
href="building.html#running-tests">"Running Tests" in the build
|
||||
documentation</a>.</p>
|
||||
<p>Since the Hotspot Gtest suite is so quick, the default is to run all
|
||||
tests. This is specified by just <code>gtest</code>, or as a fully
|
||||
qualified test descriptor <code>gtest:all</code>.</p>
|
||||
<p>If you want, you can single out an individual test or a group of
|
||||
tests, for instance <code>gtest:LogDecorations</code> or
|
||||
<code>gtest:LogDecorations.level_test_vm</code>. This can be
|
||||
particularly useful if you want to run a shaky test repeatedly.</p>
|
||||
<p>For Gtest, there is a separate test suite for each JVM variant. The
|
||||
JVM variant is defined by adding <code>/<variant></code> to the
|
||||
test descriptor, e.g. <code>gtest:Log/client</code>. If you specify no
|
||||
variant, gtest will run once for each JVM variant present (e.g. server,
|
||||
client). So if you only have the server JVM present, then
|
||||
<code>gtest:all</code> will be equivalent to
|
||||
<code>gtest:all/server</code>.</p>
|
||||
<p>Since the Hotspot Gtest suite is so quick, the default is to run all tests. This is specified by just <code>gtest</code>, or as a fully qualified test descriptor <code>gtest:all</code>.</p>
|
||||
<p>If you want, you can single out an individual test or a group of tests, for instance <code>gtest:LogDecorations</code> or <code>gtest:LogDecorations.level_test_vm</code>. This can be particularly useful if you want to run a shaky test repeatedly.</p>
|
||||
<p>For Gtest, there is a separate test suite for each JVM variant. The JVM variant is defined by adding <code>/<variant></code> to the test descriptor, e.g. <code>gtest:Log/client</code>. If you specify no variant, gtest will run once for each JVM variant present (e.g. server, client). So if you only have the server JVM present, then <code>gtest:all</code> will be equivalent to <code>gtest:all/server</code>.</p>
|
||||
<h3 id="microbenchmarks">Microbenchmarks</h3>
|
||||
<p>Which microbenchmarks to run is selected using a regular expression
|
||||
following the <code>micro:</code> test descriptor, e.g.,
|
||||
<code>micro:java.lang.reflect</code>. This delegates the test selection
|
||||
to JMH, meaning package name, class name and even benchmark method names
|
||||
can be used to select tests.</p>
|
||||
<p>Using special characters like <code>|</code> in the regular
|
||||
expression is possible, but needs to be escaped multiple times:
|
||||
<code>micro:ArrayCopy\\\\\|reflect</code>.</p>
|
||||
<p>Which microbenchmarks to run is selected using a regular expression following the <code>micro:</code> test descriptor, e.g., <code>micro:java.lang.reflect</code>. This delegates the test selection to JMH, meaning package name, class name and even benchmark method names can be used to select tests.</p>
|
||||
<p>Using special characters like <code>|</code> in the regular expression is possible, but needs to be escaped multiple times: <code>micro:ArrayCopy\\\\\|reflect</code>.</p>
|
||||
<h3 id="special-tests">Special tests</h3>
|
||||
<p>A handful of odd tests that are not covered by any other testing
|
||||
framework are accessible using the <code>special:</code> test
|
||||
descriptor. Currently, this includes <code>failure-handler</code> and
|
||||
<code>make</code>.</p>
|
||||
<p>A handful of odd tests that are not covered by any other testing framework are accessible using the <code>special:</code> test descriptor. Currently, this includes <code>failure-handler</code> and <code>make</code>.</p>
|
||||
<ul>
|
||||
<li><p>Failure handler testing is run using
|
||||
<code>special:failure-handler</code> or just
|
||||
<code>failure-handler</code> as test descriptor.</p></li>
|
||||
<li><p>Tests for the build system, including both makefiles and related
|
||||
functionality, is run using <code>special:make</code> or just
|
||||
<code>make</code> as test descriptor. This is equivalent to
|
||||
<code>special:make:all</code>.</p>
|
||||
<p>A specific make test can be run by supplying it as argument, e.g.
|
||||
<code>special:make:idea</code>. As a special syntax, this can also be
|
||||
expressed as <code>make-idea</code>, which allows for command lines as
|
||||
<code>make test-make-idea</code>.</p></li>
|
||||
<li><p>Failure handler testing is run using <code>special:failure-handler</code> or just <code>failure-handler</code> as test descriptor.</p></li>
|
||||
<li><p>Tests for the build system, including both makefiles and related functionality, is run using <code>special:make</code> or just <code>make</code> as test descriptor. This is equivalent to <code>special:make:all</code>.</p>
|
||||
<p>A specific make test can be run by supplying it as argument, e.g. <code>special:make:idea</code>. As a special syntax, this can also be expressed as <code>make-idea</code>, which allows for command lines as <code>make test-make-idea</code>.</p></li>
|
||||
</ul>
|
||||
<h2 id="test-results-and-summary">Test results and summary</h2>
|
||||
<p>At the end of the test run, a summary of all tests run will be
|
||||
presented. This will have a consistent look, regardless of what test
|
||||
suites were used. This is a sample summary:</p>
|
||||
<p>At the end of the test run, a summary of all tests run will be presented. This will have a consistent look, regardless of what test suites were used. This is a sample summary:</p>
|
||||
<pre><code>==============================
|
||||
Test summary
|
||||
==============================
|
||||
@@ -324,61 +112,20 @@ Test summary
|
||||
jtreg:nashorn/test:tier1 133 133 0 0
|
||||
==============================
|
||||
TEST FAILURE</code></pre>
|
||||
<p>Tests where the number of TOTAL tests does not equal the number of
|
||||
PASSed tests will be considered a test failure. These are marked with
|
||||
the <code>>> ... <<</code> marker for easy
|
||||
identification.</p>
|
||||
<p>The classification of non-passed tests differs a bit between test
|
||||
suites. In the summary, ERROR is used as a catch-all for tests that
|
||||
neither passed nor are classified as failed by the framework. This might
|
||||
indicate test framework error, timeout or other problems.</p>
|
||||
<p>In case of test failures, <code>make test</code> will exit with a
|
||||
non-zero exit value.</p>
|
||||
<p>All tests have their result stored in
|
||||
<code>build/$BUILD/test-results/$TEST_ID</code>, where TEST_ID is a
|
||||
path-safe conversion from the fully qualified test descriptor, e.g. for
|
||||
<code>jtreg:jdk/test:tier1</code> the TEST_ID is
|
||||
<code>jtreg_jdk_test_tier1</code>. This path is also printed in the log
|
||||
at the end of the test run.</p>
|
||||
<p>Additional work data is stored in
|
||||
<code>build/$BUILD/test-support/$TEST_ID</code>. For some frameworks,
|
||||
this directory might contain information that is useful in determining
|
||||
the cause of a failed test.</p>
|
||||
<p>Tests where the number of TOTAL tests does not equal the number of PASSed tests will be considered a test failure. These are marked with the <code>>> ... <<</code> marker for easy identification.</p>
|
||||
<p>The classification of non-passed tests differs a bit between test suites. In the summary, ERROR is used as a catch-all for tests that neither passed nor are classified as failed by the framework. This might indicate test framework error, timeout or other problems.</p>
|
||||
<p>In case of test failures, <code>make test</code> will exit with a non-zero exit value.</p>
|
||||
<p>All tests have their result stored in <code>build/$BUILD/test-results/$TEST_ID</code>, where TEST_ID is a path-safe conversion from the fully qualified test descriptor, e.g. for <code>jtreg:jdk/test:tier1</code> the TEST_ID is <code>jtreg_jdk_test_tier1</code>. This path is also printed in the log at the end of the test run.</p>
|
||||
<p>Additional work data is stored in <code>build/$BUILD/test-support/$TEST_ID</code>. For some frameworks, this directory might contain information that is useful in determining the cause of a failed test.</p>
|
||||
<h2 id="test-suite-control">Test suite control</h2>
|
||||
<p>It is possible to control various aspects of the test suites using
|
||||
make control variables.</p>
|
||||
<p>These variables use a keyword=value approach to allow multiple values
|
||||
to be set. So, for instance,
|
||||
<code>JTREG="JOBS=1;TIMEOUT_FACTOR=8"</code> will set the JTReg
|
||||
concurrency level to 1 and the timeout factor to 8. This is equivalent
|
||||
to setting <code>JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8</code>, but using
|
||||
the keyword format means that the <code>JTREG</code> variable is parsed
|
||||
and verified for correctness, so <code>JTREG="TMIEOUT_FACTOR=8"</code>
|
||||
would give an error, while <code>JTREG_TMIEOUT_FACTOR=8</code> would
|
||||
just pass unnoticed.</p>
|
||||
<p>To separate multiple keyword=value pairs, use <code>;</code>
|
||||
(semicolon). Since the shell normally eats <code>;</code>, the
|
||||
recommended usage is to write the assignment inside qoutes, e.g.
|
||||
<code>JTREG="...;..."</code>. This will also make sure spaces are
|
||||
preserved, as in
|
||||
<code>JTREG="JAVA_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"</code>.</p>
|
||||
<p>(Other ways are possible, e.g. using backslash:
|
||||
<code>JTREG=JOBS=1\;TIMEOUT_FACTOR=8</code>. Also, as a special
|
||||
technique, the string <code>%20</code> will be replaced with space for
|
||||
certain options, e.g.
|
||||
<code>JTREG=JAVA_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug</code>.
|
||||
This can be useful if you have layers of scripts and have trouble
|
||||
getting proper quoting of command line arguments through.)</p>
|
||||
<p>As far as possible, the names of the keywords have been standardized
|
||||
between test suites.</p>
|
||||
<p>It is possible to control various aspects of the test suites using make control variables.</p>
|
||||
<p>These variables use a keyword=value approach to allow multiple values to be set. So, for instance, <code>JTREG="JOBS=1;TIMEOUT_FACTOR=8"</code> will set the JTReg concurrency level to 1 and the timeout factor to 8. This is equivalent to setting <code>JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8</code>, but using the keyword format means that the <code>JTREG</code> variable is parsed and verified for correctness, so <code>JTREG="TMIEOUT_FACTOR=8"</code> would give an error, while <code>JTREG_TMIEOUT_FACTOR=8</code> would just pass unnoticed.</p>
|
||||
<p>To separate multiple keyword=value pairs, use <code>;</code> (semicolon). Since the shell normally eats <code>;</code>, the recommended usage is to write the assignment inside qoutes, e.g. <code>JTREG="...;..."</code>. This will also make sure spaces are preserved, as in <code>JTREG="JAVA_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"</code>.</p>
|
||||
<p>(Other ways are possible, e.g. using backslash: <code>JTREG=JOBS=1\;TIMEOUT_FACTOR=8</code>. Also, as a special technique, the string <code>%20</code> will be replaced with space for certain options, e.g. <code>JTREG=JAVA_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug</code>. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)</p>
|
||||
<p>As far as possible, the names of the keywords have been standardized between test suites.</p>
|
||||
<h3 id="general-keywords-test_opts">General keywords (TEST_OPTS)</h3>
|
||||
<p>Some keywords are valid across different test suites. If you want to
|
||||
run tests from multiple test suites, or just don't want to care which
|
||||
test suite specific control variable to use, then you can use the
|
||||
general TEST_OPTS control variable.</p>
|
||||
<p>There are also some keywords that applies globally to the test runner
|
||||
system, not to any specific test suites. These are also available as
|
||||
TEST_OPTS keywords.</p>
|
||||
<p>Some keywords are valid across different test suites. If you want to run tests from multiple test suites, or just don't want to care which test suite specific control variable to use, then you can use the general TEST_OPTS control variable.</p>
|
||||
<p>There are also some keywords that applies globally to the test runner system, not to any specific test suites. These are also available as TEST_OPTS keywords.</p>
|
||||
<h4 id="jobs">JOBS</h4>
|
||||
<p>Currently only applies to JTReg.</p>
|
||||
<h4 id="timeout_factor">TIMEOUT_FACTOR</h4>
|
||||
@@ -390,49 +137,28 @@ TEST_OPTS keywords.</p>
|
||||
<h4 id="aot_modules">AOT_MODULES</h4>
|
||||
<p>Applies to JTReg and GTest.</p>
|
||||
<h4 id="jcov">JCOV</h4>
|
||||
<p>This keywords applies globally to the test runner system. If set to
|
||||
<code>true</code>, it enables JCov coverage reporting for all tests run.
|
||||
To be useful, the JDK under test must be run with a JDK built with JCov
|
||||
instrumentation
|
||||
(<code>configure --with-jcov=<path to directory containing lib/jcov.jar></code>,
|
||||
<code>make jcov-image</code>).</p>
|
||||
<p>The simplest way to run tests with JCov coverage report is to use the
|
||||
special target <code>jcov-test</code> instead of <code>test</code>, e.g.
|
||||
<code>make jcov-test TEST=jdk_lang</code>. This will make sure the JCov
|
||||
image is built, and that JCov reporting is enabled.</p>
|
||||
<p>The JCov report is stored in
|
||||
<code>build/$BUILD/test-results/jcov-output/report</code>.</p>
|
||||
<p>Please note that running with JCov reporting can be very memory
|
||||
intensive.</p>
|
||||
<p>This keywords applies globally to the test runner system. If set to <code>true</code>, it enables JCov coverage reporting for all tests run. To be useful, the JDK under test must be run with a JDK built with JCov instrumentation (<code>configure --with-jcov=<path to directory containing lib/jcov.jar></code>, <code>make jcov-image</code>).</p>
|
||||
<p>The simplest way to run tests with JCov coverage report is to use the special target <code>jcov-test</code> instead of <code>test</code>, e.g. <code>make jcov-test TEST=jdk_lang</code>. This will make sure the JCov image is built, and that JCov reporting is enabled.</p>
|
||||
<p>The JCov report is stored in <code>build/$BUILD/test-results/jcov-output/report</code>.</p>
|
||||
<p>Please note that running with JCov reporting can be very memory intensive.</p>
|
||||
<h4 id="jcov_diff_changeset">JCOV_DIFF_CHANGESET</h4>
|
||||
<p>While collecting code coverage with JCov, it is also possible to find
|
||||
coverage for only recently changed code. JCOV_DIFF_CHANGESET specifies a
|
||||
source revision. A textual report will be generated showing coverage of
|
||||
the diff between the specified revision and the repository tip.</p>
|
||||
<p>The report is stored in
|
||||
<code>build/$BUILD/test-results/jcov-output/diff_coverage_report</code>
|
||||
file.</p>
|
||||
<p>While collecting code coverage with JCov, it is also possible to find coverage for only recently changed code. JCOV_DIFF_CHANGESET specifies a source revision. A textual report will be generated showing coverage of the diff between the specified revision and the repository tip.</p>
|
||||
<p>The report is stored in <code>build/$BUILD/test-results/jcov-output/diff_coverage_report</code> file.</p>
|
||||
<h3 id="jtreg-keywords">JTReg keywords</h3>
|
||||
<h4 id="jobs-1">JOBS</h4>
|
||||
<p>The test concurrency (<code>-concurrency</code>).</p>
|
||||
<p>Defaults to TEST_JOBS (if set by <code>--with-test-jobs=</code>),
|
||||
otherwise it defaults to JOBS, except for Hotspot, where the default is
|
||||
<em>number of CPU cores/2</em>, but never more than <em>memory size in
|
||||
GB/2</em>.</p>
|
||||
<p>Defaults to TEST_JOBS (if set by <code>--with-test-jobs=</code>), otherwise it defaults to JOBS, except for Hotspot, where the default is <em>number of CPU cores/2</em>, but never more than <em>memory size in GB/2</em>.</p>
|
||||
<h4 id="timeout_factor-1">TIMEOUT_FACTOR</h4>
|
||||
<p>The timeout factor (<code>-timeoutFactor</code>).</p>
|
||||
<p>Defaults to 4.</p>
|
||||
<h4 id="failure_handler_timeout">FAILURE_HANDLER_TIMEOUT</h4>
|
||||
<p>Sets the argument <code>-timeoutHandlerTimeout</code> for JTReg. The
|
||||
default value is 0. This is only valid if the failure handler is
|
||||
built.</p>
|
||||
<p>Sets the argument <code>-timeoutHandlerTimeout</code> for JTReg. The default value is 0. This is only valid if the failure handler is built.</p>
|
||||
<h4 id="test_mode">TEST_MODE</h4>
|
||||
<p>The test mode (<code>agentvm</code> or <code>othervm</code>).</p>
|
||||
<p>Defaults to <code>agentvm</code>.</p>
|
||||
<h4 id="assert">ASSERT</h4>
|
||||
<p>Enable asserts (<code>-ea -esa</code>, or none).</p>
|
||||
<p>Set to <code>true</code> or <code>false</code>. If true, adds
|
||||
<code>-ea -esa</code>. Defaults to true, except for hotspot.</p>
|
||||
<p>Set to <code>true</code> or <code>false</code>. If true, adds <code>-ea -esa</code>. Defaults to true, except for hotspot.</p>
|
||||
<h4 id="verbose">VERBOSE</h4>
|
||||
<p>The verbosity level (<code>-verbose</code>).</p>
|
||||
<p>Defaults to <code>fail,error,summary</code>.</p>
|
||||
@@ -440,172 +166,90 @@ built.</p>
|
||||
<p>What test data to retain (<code>-retain</code>).</p>
|
||||
<p>Defaults to <code>fail,error</code>.</p>
|
||||
<h4 id="max_mem">MAX_MEM</h4>
|
||||
<p>Limit memory consumption (<code>-Xmx</code> and
|
||||
<code>-vmoption:-Xmx</code>, or none).</p>
|
||||
<p>Limit memory consumption for JTReg test framework and VM under test.
|
||||
Set to 0 to disable the limits.</p>
|
||||
<p>Defaults to 512m, except for hotspot, where it defaults to 0 (no
|
||||
limit).</p>
|
||||
<p>Limit memory consumption (<code>-Xmx</code> and <code>-vmoption:-Xmx</code>, or none).</p>
|
||||
<p>Limit memory consumption for JTReg test framework and VM under test. Set to 0 to disable the limits.</p>
|
||||
<p>Defaults to 512m, except for hotspot, where it defaults to 0 (no limit).</p>
|
||||
<h4 id="max_output">MAX_OUTPUT</h4>
|
||||
<p>Set the property <code>javatest.maxOutputSize</code> for the
|
||||
launcher, to change the default JTReg log limit.</p>
|
||||
<p>Set the property <code>javatest.maxOutputSize</code> for the launcher, to change the default JTReg log limit.</p>
|
||||
<h4 id="keywords">KEYWORDS</h4>
|
||||
<p>JTReg keywords sent to JTReg using <code>-k</code>. Please be careful
|
||||
in making sure that spaces and special characters (like <code>!</code>)
|
||||
are properly quoted. To avoid some issues, the special value
|
||||
<code>%20</code> can be used instead of space.</p>
|
||||
<p>JTReg keywords sent to JTReg using <code>-k</code>. Please be careful in making sure that spaces and special characters (like <code>!</code>) are properly quoted. To avoid some issues, the special value <code>%20</code> can be used instead of space.</p>
|
||||
<h4 id="extra_problem_lists">EXTRA_PROBLEM_LISTS</h4>
|
||||
<p>Use additional problem lists file or files, in addition to the
|
||||
default ProblemList.txt located at the JTReg test roots.</p>
|
||||
<p>If multiple file names are specified, they should be separated by
|
||||
space (or, to help avoid quoting issues, the special value
|
||||
<code>%20</code>).</p>
|
||||
<p>The file names should be either absolute, or relative to the JTReg
|
||||
test root of the tests to be run.</p>
|
||||
<p>Use additional problem lists file or files, in addition to the default ProblemList.txt located at the JTReg test roots.</p>
|
||||
<p>If multiple file names are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
|
||||
<p>The file names should be either absolute, or relative to the JTReg test root of the tests to be run.</p>
|
||||
<h4 id="run_problem_lists">RUN_PROBLEM_LISTS</h4>
|
||||
<p>Use the problem lists to select tests instead of excluding them.</p>
|
||||
<p>Set to <code>true</code> or <code>false</code>. If <code>true</code>,
|
||||
JTReg will use <code>-match:</code> option, otherwise
|
||||
<code>-exclude:</code> will be used. Default is <code>false</code>.</p>
|
||||
<p>Set to <code>true</code> or <code>false</code>. If <code>true</code>, JTReg will use <code>-match:</code> option, otherwise <code>-exclude:</code> will be used. Default is <code>false</code>.</p>
|
||||
<h4 id="options">OPTIONS</h4>
|
||||
<p>Additional options to the JTReg test framework.</p>
|
||||
<p>Use <code>JTREG="OPTIONS=--help all"</code> to see all available
|
||||
JTReg options.</p>
|
||||
<p>Use <code>JTREG="OPTIONS=--help all"</code> to see all available JTReg options.</p>
|
||||
<h4 id="java_options-1">JAVA_OPTIONS</h4>
|
||||
<p>Additional Java options for running test classes (sent to JTReg as
|
||||
<code>-javaoption</code>).</p>
|
||||
<p>Additional Java options for running test classes (sent to JTReg as <code>-javaoption</code>).</p>
|
||||
<h4 id="vm_options-1">VM_OPTIONS</h4>
|
||||
<p>Additional Java options to be used when compiling and running classes
|
||||
(sent to JTReg as <code>-vmoption</code>).</p>
|
||||
<p>This option is only needed in special circumstances. To pass Java
|
||||
options to your test classes, use <code>JAVA_OPTIONS</code>.</p>
|
||||
<p>Additional Java options to be used when compiling and running classes (sent to JTReg as <code>-vmoption</code>).</p>
|
||||
<p>This option is only needed in special circumstances. To pass Java options to your test classes, use <code>JAVA_OPTIONS</code>.</p>
|
||||
<h4 id="launcher_options">LAUNCHER_OPTIONS</h4>
|
||||
<p>Additional Java options that are sent to the java launcher that
|
||||
starts the JTReg harness.</p>
|
||||
<p>Additional Java options that are sent to the java launcher that starts the JTReg harness.</p>
|
||||
<h4 id="aot_modules-1">AOT_MODULES</h4>
|
||||
<p>Generate AOT modules before testing for the specified module, or set
|
||||
of modules. If multiple modules are specified, they should be separated
|
||||
by space (or, to help avoid quoting issues, the special value
|
||||
<code>%20</code>).</p>
|
||||
<p>Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
|
||||
<h4 id="retry_count">RETRY_COUNT</h4>
|
||||
<p>Retry failed tests up to a set number of times, until they pass. This
|
||||
allows to pass the tests with intermittent failures. Defaults to 0.</p>
|
||||
<p>Retry failed tests up to a set number of times. Defaults to 0.</p>
|
||||
<h4 id="repeat_count">REPEAT_COUNT</h4>
|
||||
<p>Repeat the tests up to a set number of times, stopping at first
|
||||
failure. This helps to reproduce intermittent test failures. Defaults to
|
||||
0.</p>
|
||||
<p>Repeat the tests for a set number of times. Defaults to 0.</p>
|
||||
<h3 id="gtest-keywords">Gtest keywords</h3>
|
||||
<h4 id="repeat">REPEAT</h4>
|
||||
<p>The number of times to repeat the tests
|
||||
(<code>--gtest_repeat</code>).</p>
|
||||
<p>Default is 1. Set to -1 to repeat indefinitely. This can be
|
||||
especially useful combined with
|
||||
<code>OPTIONS=--gtest_break_on_failure</code> to reproduce an
|
||||
intermittent problem.</p>
|
||||
<p>The number of times to repeat the tests (<code>--gtest_repeat</code>).</p>
|
||||
<p>Default is 1. Set to -1 to repeat indefinitely. This can be especially useful combined with <code>OPTIONS=--gtest_break_on_failure</code> to reproduce an intermittent problem.</p>
|
||||
<h4 id="options-1">OPTIONS</h4>
|
||||
<p>Additional options to the Gtest test framework.</p>
|
||||
<p>Use <code>GTEST="OPTIONS=--help"</code> to see all available Gtest
|
||||
options.</p>
|
||||
<p>Use <code>GTEST="OPTIONS=--help"</code> to see all available Gtest options.</p>
|
||||
<h4 id="aot_modules-2">AOT_MODULES</h4>
|
||||
<p>Generate AOT modules before testing for the specified module, or set
|
||||
of modules. If multiple modules are specified, they should be separated
|
||||
by space (or, to help avoid quoting issues, the special value
|
||||
<code>%20</code>).</p>
|
||||
<p>Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
|
||||
<h3 id="microbenchmark-keywords">Microbenchmark keywords</h3>
|
||||
<h4 id="fork">FORK</h4>
|
||||
<p>Override the number of benchmark forks to spawn. Same as specifying
|
||||
<code>-f <num></code>.</p>
|
||||
<p>Override the number of benchmark forks to spawn. Same as specifying <code>-f <num></code>.</p>
|
||||
<h4 id="iter">ITER</h4>
|
||||
<p>Number of measurement iterations per fork. Same as specifying
|
||||
<code>-i <num></code>.</p>
|
||||
<p>Number of measurement iterations per fork. Same as specifying <code>-i <num></code>.</p>
|
||||
<h4 id="time">TIME</h4>
|
||||
<p>Amount of time to spend in each measurement iteration, in seconds.
|
||||
Same as specifying <code>-r <num></code></p>
|
||||
<p>Amount of time to spend in each measurement iteration, in seconds. Same as specifying <code>-r <num></code></p>
|
||||
<h4 id="warmup_iter">WARMUP_ITER</h4>
|
||||
<p>Number of warmup iterations to run before the measurement phase in
|
||||
each fork. Same as specifying <code>-wi <num></code>.</p>
|
||||
<p>Number of warmup iterations to run before the measurement phase in each fork. Same as specifying <code>-wi <num></code>.</p>
|
||||
<h4 id="warmup_time">WARMUP_TIME</h4>
|
||||
<p>Amount of time to spend in each warmup iteration. Same as specifying
|
||||
<code>-w <num></code>.</p>
|
||||
<p>Amount of time to spend in each warmup iteration. Same as specifying <code>-w <num></code>.</p>
|
||||
<h4 id="results_format">RESULTS_FORMAT</h4>
|
||||
<p>Specify to have the test run save a log of the values. Accepts the
|
||||
same values as <code>-rff</code>, i.e., <code>text</code>,
|
||||
<code>csv</code>, <code>scsv</code>, <code>json</code>, or
|
||||
<code>latex</code>.</p>
|
||||
<p>Specify to have the test run save a log of the values. Accepts the same values as <code>-rff</code>, i.e., <code>text</code>, <code>csv</code>, <code>scsv</code>, <code>json</code>, or <code>latex</code>.</p>
|
||||
<h4 id="vm_options-2">VM_OPTIONS</h4>
|
||||
<p>Additional VM arguments to provide to forked off VMs. Same as
|
||||
<code>-jvmArgs <args></code></p>
|
||||
<p>Additional VM arguments to provide to forked off VMs. Same as <code>-jvmArgs <args></code></p>
|
||||
<h4 id="options-2">OPTIONS</h4>
|
||||
<p>Additional arguments to send to JMH.</p>
|
||||
<h2 id="notes-for-specific-tests">Notes for Specific Tests</h2>
|
||||
<h3 id="docker-tests">Docker Tests</h3>
|
||||
<p>Docker tests with default parameters may fail on systems with glibc
|
||||
versions not compatible with the one used in the default docker image
|
||||
(e.g., Oracle Linux 7.6 for x86). For example, they pass on Ubuntu 16.04
|
||||
but fail on Ubuntu 18.04 if run like this on x86:</p>
|
||||
<p>Docker tests with default parameters may fail on systems with glibc versions not compatible with the one used in the default docker image (e.g., Oracle Linux 7.6 for x86). For example, they pass on Ubuntu 16.04 but fail on Ubuntu 18.04 if run like this on x86:</p>
|
||||
<pre><code>$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker"</code></pre>
|
||||
<p>To run these tests correctly, additional parameters for the correct
|
||||
docker image are required on Ubuntu 18.04 by using
|
||||
<code>JAVA_OPTIONS</code>.</p>
|
||||
<p>To run these tests correctly, additional parameters for the correct docker image are required on Ubuntu 18.04 by using <code>JAVA_OPTIONS</code>.</p>
|
||||
<pre><code>$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker" \
|
||||
JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu
|
||||
-Djdk.test.docker.image.version=latest"</code></pre>
|
||||
<h3 id="non-us-locale">Non-US locale</h3>
|
||||
<p>If your locale is non-US, some tests are likely to fail. To work
|
||||
around this you can set the locale to US. On Unix platforms simply
|
||||
setting <code>LANG="en_US"</code> in the environment before running
|
||||
tests should work. On Windows or MacOS, setting
|
||||
<code>JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US"</code>
|
||||
helps for most, but not all test cases.</p>
|
||||
<p>If your locale is non-US, some tests are likely to fail. To work around this you can set the locale to US. On Unix platforms simply setting <code>LANG="en_US"</code> in the environment before running tests should work. On Windows or MacOS, setting <code>JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US"</code> helps for most, but not all test cases.</p>
|
||||
<p>For example:</p>
|
||||
<pre><code>$ export LANG="en_US" && make test TEST=...
|
||||
$ make test JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US" TEST=...</code></pre>
|
||||
<h3 id="pkcs11-tests">PKCS11 Tests</h3>
|
||||
<p>It is highly recommended to use the latest NSS version when running
|
||||
PKCS11 tests. Improper NSS version may lead to unexpected failures which
|
||||
are hard to diagnose. For example,
|
||||
sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04
|
||||
with the default NSS version in the system. To run these tests
|
||||
correctly, the system property <code>test.nss.lib.paths</code> is
|
||||
required on Ubuntu 18.04 to specify the alternative NSS lib
|
||||
directories.</p>
|
||||
<p>It is highly recommended to use the latest NSS version when running PKCS11 tests. Improper NSS version may lead to unexpected failures which are hard to diagnose. For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04 with the default NSS version in the system. To run these tests correctly, the system property <code>test.nss.lib.paths</code> is required on Ubuntu 18.04 to specify the alternative NSS lib directories.</p>
|
||||
<p>For example:</p>
|
||||
<pre><code>$ make test TEST="jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java" \
|
||||
JTREG="JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs"</code></pre>
|
||||
<p>For more notes about the PKCS11 tests, please refer to
|
||||
test/jdk/sun/security/pkcs11/README.</p>
|
||||
<p>For more notes about the PKCS11 tests, please refer to test/jdk/sun/security/pkcs11/README.</p>
|
||||
<h3 id="client-ui-tests">Client UI Tests</h3>
|
||||
<p>Some Client UI tests use key sequences which may be reserved by the
|
||||
operating system. Usually that causes the test failure. So it is highly
|
||||
recommended to disable system key shortcuts prior testing. The steps to
|
||||
access and disable system key shortcuts for various platforms are
|
||||
provided below.</p>
|
||||
<p>Some Client UI tests use key sequences which may be reserved by the operating system. Usually that causes the test failure. So it is highly recommended to disable system key shortcuts prior testing. The steps to access and disable system key shortcuts for various platforms are provided below.</p>
|
||||
<h4 id="macos">MacOS</h4>
|
||||
<p>Choose Apple menu; System Preferences, click Keyboard, then click
|
||||
Shortcuts; select or deselect desired shortcut.</p>
|
||||
<p>For example,
|
||||
test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java
|
||||
fails on MacOS because it uses <code>CTRL + F1</code> key sequence to
|
||||
show or hide tooltip message but the key combination is reserved by the
|
||||
operating system. To run the test correctly the default global key
|
||||
shortcut should be disabled using the steps described above, and then
|
||||
deselect "Turn keyboard access on or off" option which is responsible
|
||||
for <code>CTRL + F1</code> combination.</p>
|
||||
<p>Choose Apple menu; System Preferences, click Keyboard, then click Shortcuts; select or deselect desired shortcut.</p>
|
||||
<p>For example, test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java fails on MacOS because it uses <code>CTRL + F1</code> key sequence to show or hide tooltip message but the key combination is reserved by the operating system. To run the test correctly the default global key shortcut should be disabled using the steps described above, and then deselect "Turn keyboard access on or off" option which is responsible for <code>CTRL + F1</code> combination.</p>
|
||||
<h4 id="linux">Linux</h4>
|
||||
<p>Open the Activities overview and start typing Settings; Choose
|
||||
Settings, click Devices, then click Keyboard; set or override desired
|
||||
shortcut.</p>
|
||||
<p>Open the Activities overview and start typing Settings; Choose Settings, click Devices, then click Keyboard; set or override desired shortcut.</p>
|
||||
<h4 id="windows">Windows</h4>
|
||||
<p>Type <code>gpedit</code> in the Search and then click Edit group
|
||||
policy; navigate to User Configuration -> Administrative Templates
|
||||
-> Windows Components -> File Explorer; in the right-side pane
|
||||
look for "Turn off Windows key hotkeys" and double click on it; enable
|
||||
or disable hotkeys.</p>
|
||||
<p>Type <code>gpedit</code> in the Search and then click Edit group policy; navigate to User Configuration -> Administrative Templates -> Windows Components -> File Explorer; in the right-side pane look for "Turn off Windows key hotkeys" and double click on it; enable or disable hotkeys.</p>
|
||||
<p>Note: restart is required to make the settings take effect.</p>
|
||||
<h2 id="editing-this-document">Editing this document</h2>
|
||||
<p>If you want to contribute changes to this document, edit
|
||||
<code>doc/testing.md</code> and then run
|
||||
<code>make update-build-docs</code> to generate the same changes in
|
||||
<code>doc/testing.html</code>.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
163
doc/testing.md
163
doc/testing.md
@@ -1,26 +1,21 @@
|
||||
% Testing the JDK
|
||||
|
||||
## Overview
|
||||
## Using "make test" (the run-test framework)
|
||||
|
||||
The bulk of JDK tests use [jtreg](https://openjdk.org/jtreg/), a regression
|
||||
test framework and test runner built for the JDK's specific needs. Other test
|
||||
frameworks are also used. The different test frameworks can be executed
|
||||
directly, but there is also a set of make targets intended to simplify the
|
||||
interface, and figure out how to run your tests for you.
|
||||
This new way of running tests is developer-centric. It assumes that you have
|
||||
built a JDK locally and want to test it. Running common test targets is simple,
|
||||
and more complex ad-hoc combination of tests is possible. The user interface is
|
||||
forgiving, and clearly report errors it cannot resolve.
|
||||
|
||||
## Running tests locally with `make test`
|
||||
The main target `test` uses the jdk-image as the tested product. There is
|
||||
also an alternate target `exploded-test` that uses the exploded image
|
||||
instead. Not all tests will run successfully on the exploded image, but using
|
||||
this target can greatly improve rebuild times for certain workflows.
|
||||
|
||||
This is the easiest way to get started. Assuming you've built the JDK locally,
|
||||
execute:
|
||||
|
||||
$ make test
|
||||
|
||||
This will run a default set of tests against the JDK, and present you with the
|
||||
results. `make test` is part of a family of test-related make targets which
|
||||
simplify running tests, because they invoke the various test frameworks for
|
||||
you. The "make test framework" is simple to start with, but more complex
|
||||
ad-hoc combination of tests is also possible. You can always invoke the test
|
||||
frameworks directly if you want even more control.
|
||||
Previously, `make test` was used to invoke an old system for running tests, and
|
||||
`make run-test` was used for the new test framework. For backward compatibility
|
||||
with scripts and muscle memory, `run-test` (and variants like
|
||||
`exploded-run-test` or `run-test-tier1`) are kept as aliases.
|
||||
|
||||
Some example command-lines:
|
||||
|
||||
@@ -33,20 +28,6 @@ Some example command-lines:
|
||||
$ make test TEST="micro:java.lang.reflect" MICRO="FORK=1;WARMUP_ITER=2"
|
||||
$ make exploded-test TEST=tier2
|
||||
|
||||
"tier1" and "tier2" refer to tiered testing, see further down. "TEST" is a
|
||||
test selection argument which the make test framework will use to try to
|
||||
find the tests you want. It iterates over the available test frameworks, and
|
||||
if the test isn't present in one, it tries the next one. The main target
|
||||
`test` uses the jdk-image as the tested product. There is also an alternate
|
||||
target `exploded-test` that uses the exploded image instead. Not all tests
|
||||
will run successfully on the exploded image, but using this target can
|
||||
greatly improve rebuild times for certain workflows.
|
||||
|
||||
Previously, `make test` was used to invoke an old system for running tests,
|
||||
and `make run-test` was used for the new test framework. For backward
|
||||
compatibility with scripts and muscle memory, `run-test` and variants like
|
||||
`exploded-run-test` or `run-test-tier1` are kept as aliases.
|
||||
|
||||
### Configuration
|
||||
|
||||
To be able to run JTReg tests, `configure` needs to know where to find the
|
||||
@@ -62,31 +43,6 @@ containing the core JMH and transitive dependencies. The recommended
|
||||
dependencies can be retrieved by running `sh make/devkit/createJMHBundle.sh`,
|
||||
after which `--with-jmh=build/jmh/jars` should work.
|
||||
|
||||
When tests fail or timeout, jtreg runs its failure handler to capture necessary
|
||||
data from the system where the test was run. This data can then be used to
|
||||
analyze the test failures. Collecting this data involves running various commands
|
||||
(which are listed in files residing in `test/failure_handler/src/share/conf`)
|
||||
and some of these commands use `sudo`. If the system's `sudoers` file isn't
|
||||
configured to allow running these commands, then it can result in password being
|
||||
prompted during the failure handler execution. Typically, when running locally,
|
||||
collecting this additional data isn't always necessary. To disable running the
|
||||
failure handler, use `--enable-jtreg-failure-handler=no` when running `configure`.
|
||||
If, however, you want to let the failure handler to run and don't want to be
|
||||
prompted for sudo password, then you can configure your `sudoers` file
|
||||
appropriately. Please read the necessary documentation of your operating system
|
||||
to see how to do that; here we only show one possible way of doing that - edit
|
||||
the `/etc/sudoers.d/sudoers` file to include the following line:
|
||||
|
||||
```
|
||||
johndoe ALL=(ALL) NOPASSWD: /sbin/dmesg
|
||||
```
|
||||
|
||||
This line configures `sudo` to _not_ prompt for password for the `/sbin/dmesg`
|
||||
command (this is one of the commands that is listed in the files
|
||||
at `test/failure_handler/src/share/conf`), for the user `johndoe`. Here `johndoe`
|
||||
is the user account under which the jtreg tests are run. Replace the username
|
||||
with a relevant user account of your system.
|
||||
|
||||
## Test selection
|
||||
|
||||
All functionality is available using the `test` make target. In this use case,
|
||||
@@ -110,60 +66,54 @@ if you want to shortcut the parser.
|
||||
|
||||
### Common Test Groups
|
||||
|
||||
Ideally, all tests are run for every change but this may not be practical due
|
||||
to the limited testing resources, the scope of the change, etc.
|
||||
Ideally, all tests are run for every change but this may not be practical due to the limited
|
||||
testing resources, the scope of the change, etc.
|
||||
|
||||
The source tree currently defines a few common test groups in the relevant
|
||||
`TEST.groups` files. There are test groups that cover a specific component,
|
||||
for example `hotspot_gc`. It is a good idea to look into `TEST.groups` files
|
||||
to get a sense what tests are relevant to a particular JDK component.
|
||||
The source tree currently defines a few common test groups in the relevant `TEST.groups`
|
||||
files. There are test groups that cover a specific component, for example `hotspot_gc`.
|
||||
It is a good idea to look into `TEST.groups` files to get a sense what tests are relevant
|
||||
to a particular JDK component.
|
||||
|
||||
Component-specific tests may miss some unintended consequences of a change, so
|
||||
other tests should also be run. Again, it might be impractical to run all
|
||||
tests, and therefore
|
||||
_tiered_ test groups exist. Tiered test groups are not component-specific, but
|
||||
rather cover the significant parts of the entire JDK.
|
||||
Component-specific tests may miss some unintended consequences of a change, so other
|
||||
tests should also be run. Again, it might be impractical to run all tests, and therefore
|
||||
_tiered_ test groups exist. Tiered test groups are not component-specific, but rather cover
|
||||
the significant parts of the entire JDK.
|
||||
|
||||
Multiple tiers allow balancing test coverage and testing costs. Lower test
|
||||
tiers are supposed to contain the simpler, quicker and more stable tests.
|
||||
Higher tiers are supposed to contain progressively more thorough, slower, and
|
||||
sometimes less stable tests, or the tests that require special
|
||||
configuration.
|
||||
Multiple tiers allow balancing test coverage and testing costs. Lower test tiers are supposed to
|
||||
contain the simpler, quicker and more stable tests. Higher tiers are supposed to contain
|
||||
progressively more thorough, slower, and sometimes less stable tests, or the tests that require
|
||||
special configuration.
|
||||
|
||||
Contributors are expected to run the tests for the areas that are changed, and
|
||||
the first N tiers they can afford to run, but at least tier1.
|
||||
Contributors are expected to run the tests for the areas that are changed, and the first N tiers
|
||||
they can afford to run, but at least tier1.
|
||||
|
||||
A brief description of the tiered test groups:
|
||||
|
||||
- `tier1`: This is the lowest test tier. Multiple developers run these tests
|
||||
every day. Because of the widespread use, the tests in `tier1` are
|
||||
carefully selected and optimized to run fast, and to run in the most stable
|
||||
manner. The test failures in `tier1` are usually followed up on quickly,
|
||||
either with fixes, or adding relevant tests to problem list. GitHub Actions
|
||||
workflows, if enabled, run `tier1` tests.
|
||||
- `tier1`: This is the lowest test tier. Multiple developers run these tests every day.
|
||||
Because of the widespread use, the tests in `tier1` are carefully selected and optimized to run
|
||||
fast, and to run in the most stable manner. The test failures in `tier1` are usually followed up
|
||||
on quickly, either with fixes, or adding relevant tests to problem list. GitHub Actions workflows,
|
||||
if enabled, run `tier1` tests.
|
||||
|
||||
- `tier2`: This test group covers even more ground. These contain, among other
|
||||
things, tests that either run for too long to be at `tier1`, or may require
|
||||
special configuration, or tests that are less stable, or cover the broader
|
||||
range of non-core JVM and JDK features/components(for example, XML).
|
||||
- `tier2`: This test group covers even more ground. These contain, among other things,
|
||||
tests that either run for too long to be at `tier1`, or may require special configuration,
|
||||
or tests that are less stable, or cover the broader range of non-core JVM and JDK features/components
|
||||
(for example, XML).
|
||||
|
||||
- `tier3`: This test group includes more stressful tests, the tests for corner
|
||||
cases not covered by previous tiers, plus the tests that require GUIs. As
|
||||
such, this suite should either be run with low concurrency
|
||||
(`TEST_JOBS=1`), or without headful tests(`JTREG_KEYWORDS=\!headful`), or
|
||||
both.
|
||||
- `tier3`: This test group includes more stressful tests, the tests for corner cases
|
||||
not covered by previous tiers, plus the tests that require GUIs. As such, this suite
|
||||
should either be run with low concurrency (`TEST_JOBS=1`), or without headful tests
|
||||
(`JTREG_KEYWORDS=\!headful`), or both.
|
||||
|
||||
- `tier4`: This test group includes every other test not covered by previous
|
||||
tiers. It includes, for example, `vmTestbase` suites for Hotspot, which run
|
||||
for many hours even on large machines. It also runs GUI tests, so the same
|
||||
`TEST_JOBS` and `JTREG_KEYWORDS` caveats apply.
|
||||
- `tier4`: This test group includes every other test not covered by previous tiers. It includes,
|
||||
for example, `vmTestbase` suites for Hotspot, which run for many hours even on large
|
||||
machines. It also runs GUI tests, so the same `TEST_JOBS` and `JTREG_KEYWORDS` caveats
|
||||
apply.
|
||||
|
||||
### JTReg
|
||||
|
||||
JTReg tests can be selected either by picking a JTReg test group, or a selection
|
||||
of files or directories containing JTReg tests. Documentation can be found at
|
||||
[https://openjdk.org/jtreg/](https://openjdk.org/jtreg/), note especially the
|
||||
extensive [FAQ](https://openjdk.org/jtreg/faq.html).
|
||||
of files or directories containing JTReg tests.
|
||||
|
||||
JTReg test groups can be specified either without a test root, e.g. `:tier1`
|
||||
(or `tier1`, the initial colon is optional), or with, e.g. `hotspot:tier1`,
|
||||
@@ -192,11 +142,6 @@ use a fully qualified test descriptor, add `jtreg:`, e.g.
|
||||
|
||||
### Gtest
|
||||
|
||||
**Note:** To be able to run the Gtest suite, you need to configure your build to
|
||||
be able to find a proper version of the gtest source. For details, see the
|
||||
section ["Running Tests" in the build
|
||||
documentation](building.html#running-tests).
|
||||
|
||||
Since the Hotspot Gtest suite is so quick, the default is to run all tests.
|
||||
This is specified by just `gtest`, or as a fully qualified test descriptor
|
||||
`gtest:all`.
|
||||
@@ -474,15 +419,11 @@ modules. If multiple modules are specified, they should be separated by space
|
||||
|
||||
#### RETRY_COUNT
|
||||
|
||||
Retry failed tests up to a set number of times, until they pass.
|
||||
This allows to pass the tests with intermittent failures.
|
||||
Defaults to 0.
|
||||
Retry failed tests up to a set number of times. Defaults to 0.
|
||||
|
||||
#### REPEAT_COUNT
|
||||
|
||||
Repeat the tests up to a set number of times, stopping at first failure.
|
||||
This helps to reproduce intermittent test failures.
|
||||
Defaults to 0.
|
||||
Repeat the tests for a set number of times. Defaults to 0.
|
||||
|
||||
### Gtest keywords
|
||||
|
||||
@@ -633,12 +574,6 @@ double click on it; enable or disable hotkeys.
|
||||
|
||||
Note: restart is required to make the settings take effect.
|
||||
|
||||
## Editing this document
|
||||
|
||||
If you want to contribute changes to this document, edit `doc/testing.md` and
|
||||
then run `make update-build-docs` to generate the same changes in
|
||||
`doc/testing.html`.
|
||||
|
||||
---
|
||||
# Override some definitions in the global css file that are not optimal for
|
||||
# this document.
|
||||
|
||||
230
jb/jdkdiff.py
Executable file
230
jb/jdkdiff.py
Executable file
@@ -0,0 +1,230 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import math
|
||||
import os.path
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
|
||||
def fatal(msg):
|
||||
sys.stderr.write(f"[fatal] {msg}\n")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def verbose(options, *msg):
|
||||
if options.verbose:
|
||||
sys.stdout.write(f"[verbose] ")
|
||||
sys.stdout.write(*msg)
|
||||
sys.stdout.write('\n')
|
||||
|
||||
|
||||
def first_line(str):
|
||||
return "" if not str else str.splitlines()[0]
|
||||
|
||||
|
||||
class Options:
|
||||
def __init__(self):
|
||||
ap = argparse.ArgumentParser(description="Show bugfixes differences between JBR and OpenJDK git repos",
|
||||
epilog="Example: %(prog)s --jdk ./jdk11u/ --jbr ./JetBrainsRuntime/ --path src/hotspot --limit 200")
|
||||
ap.add_argument('--jdk', dest='jdkpath', help='path to OpenJDK git repo', required=True)
|
||||
ap.add_argument('--jbr', dest='jbrpath', help='path to JBR git repo', required=True)
|
||||
ap.add_argument('--path', dest='path', help='limit to changes in this path (relative to git root)')
|
||||
ap.add_argument('--limit', dest='limit', help='limit to this many log entries in --jdk repo', type=int, default=-1)
|
||||
ap.add_argument('-o', dest="output_dir", help="save patches to this directory (created if necessary)")
|
||||
ap.add_argument('-v', dest='verbose', help="verbose output", default=False, action='store_true')
|
||||
args = ap.parse_args()
|
||||
|
||||
if not os.path.isdir(args.jdkpath):
|
||||
fatal(f"{args.jdkpath} not a directory")
|
||||
|
||||
if not os.path.isdir(args.jbrpath):
|
||||
fatal(f"{args.jbrpath} not a directory")
|
||||
|
||||
if not git_is_available():
|
||||
fatal("can't run git commands; make sure git is in PATH")
|
||||
|
||||
self.jdkpath = args.jdkpath
|
||||
self.jbrpath = args.jbrpath
|
||||
self.path = args.path
|
||||
self.limit = args.limit
|
||||
self.output_dir = args.output_dir
|
||||
self.verbose = args.verbose
|
||||
|
||||
|
||||
class GitRepo:
|
||||
def __init__(self, rootpath):
|
||||
self.rootpath = rootpath
|
||||
|
||||
def run_git_cmd(self, git_args):
|
||||
args = ["git", "-C", self.rootpath]
|
||||
args.extend(git_args)
|
||||
# print(f"Runnig git cmd '{' '.join(args)}'")
|
||||
p = subprocess.run(args, capture_output=True, text=True)
|
||||
if p.returncode != 0:
|
||||
fatal(f"git returned non-zero code in {self.rootpath} ({first_line(p.stderr)})")
|
||||
return p.stdout
|
||||
|
||||
def save_git_cmd(self, fname, git_args):
|
||||
args = ["git", "-C", self.rootpath]
|
||||
args.extend(git_args)
|
||||
# print(f"Runnig git cmd '{' '.join(args)}'")
|
||||
with open(fname, "w") as stdout_file:
|
||||
p = subprocess.run(args, stdout=stdout_file)
|
||||
if p.returncode != 0:
|
||||
fatal(f"git returned non-zero code in {self.rootpath} ({first_line(p.stderr)})")
|
||||
|
||||
def current_branch(self):
|
||||
branch_name = self.run_git_cmd(["branch", "--show-current"]).strip()
|
||||
return branch_name
|
||||
|
||||
def log(self, path=None, limit=None):
|
||||
cmds = ["log", "--no-decorate"]
|
||||
if limit:
|
||||
cmds.extend(["-n", str(limit)])
|
||||
if path:
|
||||
cmds.append(path)
|
||||
full_log = self.run_git_cmd(cmds)
|
||||
return full_log
|
||||
|
||||
|
||||
class Commit:
|
||||
def __init__(self, lines):
|
||||
self.sha = lines[0].split()[1]
|
||||
self.message = ""
|
||||
self.bugid = None
|
||||
|
||||
# Commit message starts after one blank line
|
||||
read_message = False
|
||||
for l in lines:
|
||||
if read_message:
|
||||
self.message += l + "\n"
|
||||
if not read_message and l == "":
|
||||
read_message = True
|
||||
|
||||
if self.message and self.message != "" and ":" in self.message:
|
||||
maybe_bugid = self.message.split(":")[0].strip()
|
||||
if 10 >= len(maybe_bugid) >= 4:
|
||||
self.bugid = maybe_bugid
|
||||
|
||||
|
||||
class History:
|
||||
def __init__(self, log):
|
||||
log_itr = iter(log.splitlines())
|
||||
self.commits = []
|
||||
commit_lines = []
|
||||
for line in log_itr:
|
||||
if line.startswith("commit ") and len(commit_lines) > 0:
|
||||
commit = Commit(commit_lines)
|
||||
self.commits.append(commit)
|
||||
commit_lines = []
|
||||
commit_lines.append(line)
|
||||
|
||||
if len(commit_lines) > 0:
|
||||
commit = Commit(commit_lines)
|
||||
self.commits.append(commit)
|
||||
|
||||
def contains(self, str):
|
||||
return any(str in commit.message for commit in self.commits)
|
||||
|
||||
def size(self):
|
||||
return len(self.commits)
|
||||
|
||||
|
||||
def print_explanation(options, jdk, jbr):
|
||||
verbose(options, f"Reading history from '{jdk.rootpath}' on branch '{jdk.current_branch()}'")
|
||||
if options.path:
|
||||
verbose(options, f"\t(only under '{options.path}')")
|
||||
verbose(options, f"Searching for same fixes in '{jbr.rootpath}' on branch '{jbr.current_branch()}'")
|
||||
|
||||
|
||||
def git_is_available():
|
||||
p = None
|
||||
try:
|
||||
p = subprocess.run(["git", "--help"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
except:
|
||||
pass
|
||||
return p is not None and p.returncode == 0
|
||||
|
||||
|
||||
def main():
|
||||
check_python_min_requirements()
|
||||
|
||||
options = Options()
|
||||
|
||||
jdk = GitRepo(options.jdkpath)
|
||||
jbr = GitRepo(options.jbrpath)
|
||||
|
||||
print_explanation(options, jdk, jbr)
|
||||
|
||||
commits_to_save = []
|
||||
try:
|
||||
jdk_log = jdk.log(options.path, options.limit)
|
||||
jdk_history = History(jdk_log)
|
||||
|
||||
jbr_log = jbr.log(options.path)
|
||||
jbr_history = History(jbr_log)
|
||||
|
||||
verbose(options, f"Read {jdk_history.size()} commits in JDK, {jbr_history.size()} in JBR")
|
||||
|
||||
for c in jdk_history.commits:
|
||||
if c.bugid:
|
||||
verbose(options, f"Looking for bugfix for {c.bugid}")
|
||||
if not jbr_history.contains(c.bugid):
|
||||
commits_to_save.append(c)
|
||||
print(f"[note] Fix for {c.bugid} not found in JBR ({jbr.rootpath})")
|
||||
print(f" commit {c.sha}")
|
||||
print(f" {first_line(c.message).strip()}")
|
||||
except KeyboardInterrupt:
|
||||
fatal("Interrupted")
|
||||
|
||||
if len(commits_to_save) > 0 and options.output_dir:
|
||||
print()
|
||||
if not os.path.exists(options.output_dir):
|
||||
verbose(options, f"Creating output directory {options.output_dir}")
|
||||
os.makedirs(options.output_dir)
|
||||
nzeroes = len(str(len(commits_to_save)))
|
||||
for i, c in enumerate(reversed(commits_to_save)):
|
||||
fname = os.path.join(options.output_dir, f"{str(i).zfill(nzeroes)}-{c.bugid}.patch")
|
||||
print(f"[note] {c.bugid} saved as {fname}")
|
||||
fname = os.path.abspath(fname)
|
||||
jdk.save_git_cmd(fname, ["format-patch", "-1", c.sha, "--stdout"])
|
||||
|
||||
script_fname = os.path.join(options.output_dir, "apply.sh")
|
||||
with open(script_fname, "w") as script_file:
|
||||
print(apply_script_code.format(os.path.abspath(jbr.rootpath), os.path.abspath(options.output_dir)),
|
||||
file=script_file)
|
||||
print(f"[note] Execute 'bash {script_fname}' to apply patches to {jbr.rootpath}")
|
||||
|
||||
|
||||
def check_python_min_requirements():
|
||||
if sys.version_info < (3, 6):
|
||||
fatal("Minimum version 3.6 is required to run this script")
|
||||
|
||||
|
||||
apply_script_code = """
|
||||
#!/bin/bash
|
||||
|
||||
GITROOT={0}
|
||||
PATCHROOT={1}
|
||||
|
||||
cd $PATCHROOT || exit 1
|
||||
PATCHES=$(find $PATCHROOT -name '*.patch' | sort -n)
|
||||
|
||||
for P in $PATCHES; do
|
||||
git -C $GITROOT am $P
|
||||
if [ $? != 0 ]; then
|
||||
mv "$P" "$P.failed"
|
||||
echo "[ERROR] Patch $P did not apply cleanly. Try applying it manually."
|
||||
echo "[NOTE] Execute this script to apply the remaining patches."
|
||||
exit 1
|
||||
else
|
||||
mv "$P" "$P.done"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "[NOTE] Done applying patches; check $PATCHROOT for .patch and .patch.failed to see if all have been applied."
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
13
jb/project/docker/Dockerfile
Normal file
13
jb/project/docker/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
# jetbrains/runtime:jbr15env
|
||||
FROM centos:7
|
||||
RUN yum -y install centos-release-scl
|
||||
RUN yum -y install devtoolset-8
|
||||
RUN yum -y install zip bzip2 unzip tar wget make autoconf automake libtool gcc gcc-c++ libstdc++-devel alsa-devel cups-devel xorg-x11-devel libjpeg62-devel giflib-devel freetype-devel file which libXtst-devel libXt-devel libXrender-devel alsa-lib-devel fontconfig-devel libXrandr-devel libXi-devel git
|
||||
# Install Java 16
|
||||
RUN wget https://cdn.azul.com/zulu/bin/zulu17.28.13-ca-jdk17.0.0-linux_x64.tar.gz \
|
||||
-O - | tar xz -C /
|
||||
RUN mv /zulu17.28.13-ca-jdk17.0.0-linux_x64 /jdk17.0.0
|
||||
ENV PATH /opt/rh/devtoolset-8/root/usr/bin:$PATH
|
||||
RUN mkdir .git
|
||||
RUN git config user.email "teamcity@jetbrains.com"
|
||||
RUN git config user.name "builduser"
|
||||
47
jb/project/docker/Dockerfile.aarch64
Normal file
47
jb/project/docker/Dockerfile.aarch64
Normal file
@@ -0,0 +1,47 @@
|
||||
# NOTE: This Dockerfile is meant to be used from the mkdocker_aarch64.sh script.
|
||||
|
||||
# Pull a concrete version of Linux that does NOT recieve updates after it's
|
||||
# been created. This is so that the image is as stable as possible to make
|
||||
# image creation reproducible.
|
||||
# NB: this also means there may be no security-related fixes there, need to
|
||||
# move the version to the next manually.
|
||||
FROM arm64v8/ubuntu:focal-20211006
|
||||
|
||||
# Install the necessary build tools
|
||||
RUN export DEBIAN_FRONTEND=noninteractive \
|
||||
export DEBCONF_NONINTERACTIVE_SEEN=true && \
|
||||
echo 'tzdata tzdata/Areas select Etc' | debconf-set-selections; \
|
||||
echo 'tzdata tzdata/Zones/Etc select UTC' | debconf-set-selections; \
|
||||
apt-get update -qy && \
|
||||
apt-get install -qy \
|
||||
autoconf \
|
||||
build-essential \
|
||||
bzip2 \
|
||||
file \
|
||||
g++-10=10.3.0-1ubuntu1~20.04 \
|
||||
gcc-10=10.3.0-1ubuntu1~20.04 \
|
||||
git \
|
||||
libasound2-dev \
|
||||
libcups2-dev \
|
||||
libfontconfig1-dev \
|
||||
libx11-dev \
|
||||
libxext-dev \
|
||||
libxrandr-dev \
|
||||
libxrender-dev \
|
||||
libxt-dev \
|
||||
libxtst-dev \
|
||||
make \
|
||||
tar \
|
||||
unzip \
|
||||
zip && \
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 && \
|
||||
apt-get clean -qy && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# Set up boot JDK for building
|
||||
COPY boot_jdk.tar.gz /jdk17/
|
||||
RUN cd /jdk17 && tar --strip-components=1 -xzf boot_jdk.tar.gz && rm /jdk17/boot_jdk.tar.gz
|
||||
ENV BOOT_JDK=/jdk17
|
||||
|
||||
RUN git config --global user.email "teamcity@jetbrains.com" && \
|
||||
git config --global user.name "builduser"
|
||||
7
jb/project/docker/Dockerfile.x86
Normal file
7
jb/project/docker/Dockerfile.x86
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM i386/ubuntu:xenial
|
||||
|
||||
RUN linux32 apt-get update && apt-get install -y --no-install-recommends apt-utils
|
||||
COPY jbrsdk-11.0.5-b1 /jbrsdk-11.0.5-b1
|
||||
RUN linux32 apt-get -y install file build-essential zip unzip curl libx11-dev libxext-dev \
|
||||
libxrender-dev libxrandr-dev libxtst-dev libxt-dev libcups2-dev libasound2-data \
|
||||
libpng12-0 libasound2 libfreetype6 libfontconfig1-dev libasound2-dev autoconf
|
||||
26
jb/project/docker/mkdocker_aarch64.sh
Executable file
26
jb/project/docker/mkdocker_aarch64.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# This script creates a Docker image suitable for building AArch64 variant
|
||||
# of the JetBrains Runtime "dev" version.
|
||||
|
||||
BOOT_JDK_REMOTE_FILE=zulu17.30.15-ca-jdk17.0.1-linux_aarch64.tar.gz
|
||||
BOOT_JDK_SHA=4d9c9116eb0cdd2d7fb220d6d27059f4bf1b7e95cc93d5512bd8ce3791af86c7
|
||||
BOOT_JDK_LOCAL_FILE=boot_jdk.tar.gz
|
||||
|
||||
if [ ! -f $BOOT_JDK_LOCAL_FILE ]; then
|
||||
# Obtain "boot JDK" from outside of the container.
|
||||
wget -nc https://cdn.azul.com/zulu/bin/${BOOT_JDK_REMOTE_FILE} -O $BOOT_JDK_LOCAL_FILE
|
||||
else
|
||||
echo "boot JDK \"$BOOT_JDK_LOCAL_FILE\" present, skipping download"
|
||||
fi
|
||||
|
||||
# Verify that what we've downloaded can be trusted.
|
||||
sha256sum -c - <<EOF
|
||||
$BOOT_JDK_SHA *$BOOT_JDK_LOCAL_FILE
|
||||
EOF
|
||||
|
||||
docker build -t jbrdevenv_arm64v8 -f Dockerfile.aarch64 .
|
||||
|
||||
# NB: the resulting container can (and should) be used without the network
|
||||
# connection (--network none) during build in order to reduce the chance
|
||||
# of build contamination.
|
||||
9
jb/project/idea-project-files/copyright/JetBrains.xml
Normal file
9
jb/project/idea-project-files/copyright/JetBrains.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="notice" value="Copyright &#36;originalComment.match("Copyright (\d+)", 1, "-")&#36;today.year JetBrains s.r.o. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. This code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 only, as published by the Free Software Foundation. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more details (a copy is included in the LICENSE file that accompanied this code). You should have received a copy of the GNU General Public License version 2 along with this work; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA or visit www.oracle.com if you need additional information or have any questions." />
|
||||
<option name="keyword" value="Copyright" />
|
||||
<option name="allowReplaceKeyword" value="JetBrains" />
|
||||
<option name="myName" value="JetBrains" />
|
||||
<option name="myLocal" value="true" />
|
||||
</copyright>
|
||||
</component>
|
||||
@@ -0,0 +1,3 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="JetBrains" />
|
||||
</component>
|
||||
1
jb/project/idea-project-files/jdk-clion/.idea/.name
generated
Normal file
1
jb/project/idea-project-files/jdk-clion/.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
JetBrainsRuntime
|
||||
9
jb/project/idea-project-files/jdk-clion/.idea/copyright/JetBrains.xml
generated
Normal file
9
jb/project/idea-project-files/jdk-clion/.idea/copyright/JetBrains.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="notice" value="Copyright 2000-&#36;today.year JetBrains s.r.o. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License." />
|
||||
<option name="keyword" value="Copyright" />
|
||||
<option name="allowReplaceKeyword" value="JetBrains" />
|
||||
<option name="myName" value="JetBrains" />
|
||||
<option name="myLocal" value="true" />
|
||||
</copyright>
|
||||
</component>
|
||||
3
jb/project/idea-project-files/jdk-clion/.idea/copyright/profiles_settings.xml
generated
Normal file
3
jb/project/idea-project-files/jdk-clion/.idea/copyright/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,3 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="JetBrains" />
|
||||
</component>
|
||||
20
jb/project/idea-project-files/jdk-clion/.idea/vcs.xml
generated
Normal file
20
jb/project/idea-project-files/jdk-clion/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="IssueNavigationConfiguration">
|
||||
<option name="links">
|
||||
<list>
|
||||
<IssueNavigationLink>
|
||||
<option name="issueRegexp" value="(?:^|\s|\p{Punct})([A-Z]+\-\d+)(?=$|\s|\p{Punct})" />
|
||||
<option name="linkRegexp" value="https://youtrack.jetbrains.com/issue/$1" />
|
||||
</IssueNavigationLink>
|
||||
<IssueNavigationLink>
|
||||
<option name="issueRegexp" value="(?:^|\s|\p{Punct})(?:JDK-)?(\d{7})(?=$|\s|\p{Punct})" />
|
||||
<option name="linkRegexp" value="https://bugs.openjdk.java.net/browse/JDK-$1" />
|
||||
</IssueNavigationLink>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
13
jb/project/idea-project-files/jetbrains.api.iml
Normal file
13
jb/project/idea-project-files/jetbrains.api.iml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$/src/jetbrains.api">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/jetbrains.api/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/jetbrains.api/templates" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
12
jb/project/idea-project-files/modules.xml
Normal file
12
jb/project/idea-project-files/modules.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/jdk.iml" filepath="$PROJECT_DIR$/.idea/jdk.iml" />
|
||||
###MODULE_IMLS###
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/jetbrains.api.iml" filepath="$PROJECT_DIR$/.idea/jetbrains.api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/test.iml" filepath="$PROJECT_DIR$/.idea/test.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
20
jb/project/idea-project-files/vcs.xml
Normal file
20
jb/project/idea-project-files/vcs.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="IssueNavigationConfiguration">
|
||||
<option name="links">
|
||||
<list>
|
||||
<IssueNavigationLink>
|
||||
<option name="issueRegexp" value="(?:^|\s|\p{Punct})([A-Z]+\-\d+)(?=$|\s|\p{Punct})" />
|
||||
<option name="linkRegexp" value="https://youtrack.jetbrains.com/issue/$1" />
|
||||
</IssueNavigationLink>
|
||||
<IssueNavigationLink>
|
||||
<option name="issueRegexp" value="(?:^|\s|\p{Punct})(?:JDK-)?(\d{7})(?=$|\s|\p{Punct})" />
|
||||
<option name="linkRegexp" value="https://bugs.openjdk.java.net/browse/JDK-$1" />
|
||||
</IssueNavigationLink>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
135
jb/project/java-gradle/build.gradle
Normal file
135
jb/project/java-gradle/build.gradle
Normal file
@@ -0,0 +1,135 @@
|
||||
apply plugin: 'java'
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
def test_jvm = {
|
||||
if (project.hasProperty('jbsdkhome')) {
|
||||
file(jbsdkhome + (OperatingSystem.current().isWindows()?"/bin/java.exe" : "/bin/java")).absolutePath
|
||||
} else {
|
||||
if (OperatingSystem.current().isMacOsX()) {
|
||||
file('../../../build/macosx-x86_64-normal-server-release/images/jdk-bundle/jdk-11.0.4.jdk/Contents/Home/bin/java').absolutePath
|
||||
} else if (OperatingSystem.current().isLinux()) {
|
||||
file('../../../build/linux-x86_64-normal-server-release/images/jdk/bin/java').absolutePath
|
||||
} else {
|
||||
file('../../../build/windows-x86_64-normal-server-release/images/jdk/bin/java.exe').absolutePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile('junit:junit:4.12'){
|
||||
exclude group: 'org.hamcrest'
|
||||
}
|
||||
testCompile 'org.hamcrest:hamcrest-library:1.3'
|
||||
testCompile 'net.java.dev.jna:jna:4.4.0'
|
||||
testCompile 'com.twelvemonkeys.imageio:imageio-tiff:3.3.2'
|
||||
testCompile 'org.apache.commons:commons-lang3:3.0'
|
||||
}
|
||||
|
||||
def jdk_modules = ["java.base", "java.logging", "java.prefs",
|
||||
"java.se.ee", "java.sql", "java.datatransfer",
|
||||
"java.management", "java.rmi", "java.security.jgss",
|
||||
"java.sql.rowset", "java.desktop", "java.management.rmi",
|
||||
"java.scripting", "java.security.sasl", "java.transaction",
|
||||
"java.instrument", "java.naming", "java.se",
|
||||
"java.smartcardio", "java.xml.crypto"]
|
||||
|
||||
def jdk_class_dirs = []
|
||||
|
||||
jdk_modules.collect(jdk_class_dirs) {
|
||||
new File("../../../src/" + it + "/share/classes")
|
||||
}
|
||||
|
||||
if (OperatingSystem.current().isMacOsX())
|
||||
jdk_modules.collect(jdk_class_dirs) {
|
||||
"../../../src/" + it + "/macosx/classes"
|
||||
}
|
||||
else if (OperatingSystem.current().isLinux()) {
|
||||
jdk_modules.collect(jdk_class_dirs) {
|
||||
"../../../src/" + it + "/solaris/classes"
|
||||
}
|
||||
jdk_modules.collect(jdk_class_dirs) {
|
||||
"../../../src/" + it + "/unix/classes"
|
||||
}
|
||||
} else
|
||||
jdk_modules.collect(jdk_class_dirs) {
|
||||
"../../../src/" + it + "/windows/classes"
|
||||
}
|
||||
|
||||
sourceSets.main.java.srcDirs = jdk_class_dirs
|
||||
|
||||
sourceSets {
|
||||
test {
|
||||
java {
|
||||
srcDir "../../../test/jdk/jbu"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test.dependsOn.clear()
|
||||
|
||||
test.dependsOn tasks.compileTestJava
|
||||
|
||||
test {
|
||||
systemProperty "jb.java2d.metal", "true"
|
||||
systemProperty "testdata", file('../../../test/jdk/jbu/testdata').absolutePath
|
||||
|
||||
// Generate golden images for DroidFontTest and MixedTextTest
|
||||
// systemProperty "gentestdata", ""
|
||||
|
||||
// Enable Java2D logging (https://confluence.jetbrains.com/display/JRE/Java2D+Rendering+Logging)
|
||||
// systemProperty "sun.java2d.trace", "log"
|
||||
// systemProperty "sun.java2d.trace", "log,pimpl"
|
||||
|
||||
outputs.upToDateWhen { false }
|
||||
executable = test_jvm()
|
||||
|
||||
// Enable async/dtrace profiler
|
||||
jvmArgs "-XX:+PreserveFramePointer"
|
||||
// Enable native J2D logging (only in debug build)
|
||||
// Can be turned on for J2D by adding "#define DEBUG 1" into jdk/src/share/native/sun/java2d/Trace.h
|
||||
|
||||
// environment 'J2D_TRACE_LEVEL', '4'
|
||||
}
|
||||
|
||||
def buildDir = project.buildscript.sourceFile.parentFile.parentFile.parentFile.parentFile
|
||||
|
||||
def make_cmd = "make"
|
||||
if (OperatingSystem.current().isWindows()) {
|
||||
def cyg_make_cmd = new File("c:/cygwin64/bin/make.exe")
|
||||
if (cyg_make_cmd.exists()) make_cmd = cyg_make_cmd.absolutePath
|
||||
}
|
||||
def test_run = false
|
||||
task make_images {
|
||||
doLast {
|
||||
if (!test_run) {
|
||||
def pb = new ProcessBuilder().command(make_cmd.toString(), "-C", buildDir.absolutePath, "images")
|
||||
def proc = pb.redirectErrorStream(true).start()
|
||||
proc.inputStream.eachLine { println it }
|
||||
assert proc.waitFor() == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task make_clean {
|
||||
doLast {
|
||||
def pb = new ProcessBuilder().command(make_cmd.toString(), "-C", buildDir.absolutePath, "clean")
|
||||
def proc = pb.redirectErrorStream(true).start()
|
||||
proc.inputStream.eachLine { println it }
|
||||
assert proc.waitFor() == 0
|
||||
}
|
||||
}
|
||||
|
||||
task run_test {
|
||||
doLast {
|
||||
test_run = true
|
||||
}
|
||||
}
|
||||
|
||||
tasks.cleanTest.dependsOn tasks.run_test
|
||||
classes.dependsOn.clear()
|
||||
classes.dependsOn tasks.make_images
|
||||
tasks.cleanClasses.dependsOn tasks.make_clean
|
||||
16
jb/project/tools/common/scripts/build-jbr-api.sh
Normal file
16
jb/project/tools/common/scripts/build-jbr-api.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
# $1 - Boot JDK
|
||||
# $2 - JBR part of API version
|
||||
|
||||
cd "`dirname "$0"`/../../../../.."
|
||||
PWD="`pwd`"
|
||||
CONF="$PWD/build/jbr-api.conf"
|
||||
./configure --with-debug-level=release --with-boot-jdk=$1 || exit $?
|
||||
make jbr-api CONF=release MAKEOVERRIDES= "JBR_API_CONF_FILE=$CONF" JBR_API_JBR_VERSION=$2 || exit $?
|
||||
. $CONF || exit $?
|
||||
echo "##teamcity[buildNumber '$VERSION']"
|
||||
cp "$JAR" ./jbr-api-${VERSION}.jar || exit $?
|
||||
cp "$SOURCES_JAR" ./jbr-api-${VERSION}-sources.jar || exit $?
|
||||
echo "##teamcity[publishArtifacts '$PWD/jbr-api-${VERSION}.jar']"
|
||||
echo "##teamcity[publishArtifacts '$PWD/jbr-api-${VERSION}-sources.jar']"
|
||||
95
jb/project/tools/common/scripts/common.sh
Normal file
95
jb/project/tools/common/scripts/common.sh
Normal file
@@ -0,0 +1,95 @@
|
||||
VENDOR_NAME="JetBrains s.r.o."
|
||||
VENDOR_VERSION_STRING="JBR-${JBSDK_VERSION_WITH_DOTS}.${JDK_BUILD_NUMBER}-${build_number}"
|
||||
[ -z "$bundle_type" ] || VENDOR_VERSION_STRING="${VENDOR_VERSION_STRING}-${bundle_type}"
|
||||
|
||||
do_reset_changes=0
|
||||
do_reset_dcevm=0
|
||||
HEAD_REVISION=0
|
||||
|
||||
OS_NAME=$(uname -s)
|
||||
# Enable reproducible builds
|
||||
TZ=UTC
|
||||
export TZ
|
||||
SOURCE_DATE_EPOCH="$(git log -1 --pretty=%ct)"
|
||||
export SOURCE_DATE_EPOCH
|
||||
|
||||
case "$OS_NAME" in
|
||||
Linux)
|
||||
COPYRIGHT_YEAR="$(date --utc --date=@$SOURCE_DATE_EPOCH +%Y)"
|
||||
BUILD_TIME="$(date --utc --date=@$SOURCE_DATE_EPOCH +%F)"
|
||||
REPRODUCIBLE_TAR_OPTS="--mtime=@$SOURCE_DATE_EPOCH --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime"
|
||||
;;
|
||||
Darwin)
|
||||
COPYRIGHT_YEAR="$(date -u -r $SOURCE_DATE_EPOCH +%Y)"
|
||||
BUILD_TIME="$(date -u -r $SOURCE_DATE_EPOCH +%F)"
|
||||
TOUCH_TIME="$(date -u -r $SOURCE_DATE_EPOCH +%Y%m%d%H%M.%S)"
|
||||
REPRODUCIBLE_TAR_OPTS="--uid 0 --gid 0 --numeric-owner"
|
||||
;;
|
||||
*)
|
||||
# TODO: Windows
|
||||
;;
|
||||
esac
|
||||
|
||||
REPRODUCIBLE_BUILD_OPTS="--enable-reproducible-build
|
||||
--with-source-date=$SOURCE_DATE_EPOCH
|
||||
--with-hotspot-build-time=$BUILD_TIME
|
||||
--with-copyright-year=$COPYRIGHT_YEAR
|
||||
--with-native-debug-symbols=none
|
||||
--with-build-user=builduser"
|
||||
|
||||
function do_exit() {
|
||||
exit_code=$1
|
||||
[ $do_reset_changes -eq 1 ] && git checkout HEAD modules.list src/java.desktop/share/classes/module-info.java
|
||||
if [ $do_reset_dcevm -eq 1 ]; then
|
||||
[ ! -z $HEAD_REVISION ] && git reset --hard $HEAD_REVISION
|
||||
fi
|
||||
exit "$exit_code"
|
||||
}
|
||||
|
||||
function update_jsdk_mods() {
|
||||
__jsdk=$1
|
||||
__jcef_mods=$2
|
||||
__orig_jsdk_mods=$3
|
||||
__updated_jsdk_mods=$4
|
||||
|
||||
# re-create java.desktop.jmod with updated module-info.class
|
||||
tmp=.java.desktop.$$.tmp
|
||||
mkdir "$tmp" || exit $?
|
||||
"$__jsdk"/bin/jmod extract --dir "$tmp" "$__orig_jsdk_mods"/java.desktop.jmod || exit $?
|
||||
"$__jsdk"/bin/javac \
|
||||
--patch-module java.desktop="$__orig_jsdk_mods"/java.desktop.jmod \
|
||||
--module-path "$__jcef_mods" -d "$tmp"/classes src/java.desktop/share/classes/module-info.java || exit $?
|
||||
"$__jsdk"/bin/jmod \
|
||||
create --class-path "$tmp"/classes --config "$tmp"/conf --header-files "$tmp"/include --legal-notice "$tmp"/legal --libs "$tmp"/lib \
|
||||
java.desktop.jmod || exit $?
|
||||
mv java.desktop.jmod "$__updated_jsdk_mods" || exit $?
|
||||
rm -rf "$tmp"
|
||||
|
||||
# re-create java.base.jmod with updated hashes
|
||||
tmp=.java.base.$$.tmp
|
||||
mkdir "$tmp" || exit $?
|
||||
hash_modules=$("$JSDK"/bin/jmod describe "$__orig_jsdk_mods"/java.base.jmod | grep hashes | awk '{print $2}' | tr '\n' '|' | sed s/\|$//) || exit $?
|
||||
"$__jsdk"/bin/jmod extract --dir "$tmp" "$__orig_jsdk_mods"/java.base.jmod || exit $?
|
||||
rm "$__updated_jsdk_mods"/java.base.jmod || exit $? # temp exclude from path
|
||||
"$__jsdk"/bin/jmod \
|
||||
create --module-path "$__updated_jsdk_mods" --hash-modules "$hash_modules" \
|
||||
--class-path "$tmp"/classes --cmds "$tmp"/bin --config "$tmp"/conf --header-files "$tmp"/include --legal-notice "$tmp"/legal --libs "$tmp"/lib \
|
||||
java.base.jmod || exit $?
|
||||
mv java.base.jmod "$__updated_jsdk_mods" || exit $?
|
||||
rm -rf "$tmp"
|
||||
}
|
||||
|
||||
function get_mods_list() {
|
||||
__mods=$1
|
||||
echo $(ls $__mods) | sed s/\.jmod/,/g | sed s/,$//g | sed s/' '//g
|
||||
}
|
||||
|
||||
function copy_jmods() {
|
||||
__mods_list=$1
|
||||
__jmods_from=$2
|
||||
__jmods_to=$3
|
||||
|
||||
mkdir -p $__jmods_to
|
||||
|
||||
echo "${__mods_list}," | while read -d, mod; do cp $__jmods_from/$mod.jmod $__jmods_to/; done
|
||||
}
|
||||
87
jb/project/tools/linux/scripts/mkimages_aarch64.sh
Executable file
87
jb/project/tools/linux/scripts/mkimages_aarch64.sh
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# The following parameters must be specified:
|
||||
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
|
||||
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
|
||||
# build_number - specifies the number of JetBrainsRuntime build
|
||||
#
|
||||
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
#
|
||||
# $ ./java --version
|
||||
# openjdk 11.0.6 2020-01-14
|
||||
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
|
||||
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
|
||||
#
|
||||
|
||||
JBSDK_VERSION=$1
|
||||
JDK_BUILD_NUMBER=$2
|
||||
build_number=$3
|
||||
|
||||
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
|
||||
|
||||
source jb/project/tools/common/scripts/common.sh
|
||||
|
||||
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
|
||||
|
||||
sh configure \
|
||||
--with-debug-level=release \
|
||||
--with-vendor-name="${VENDOR_NAME}" \
|
||||
--with-vendor-version-string="${VENDOR_VERSION_STRING}" \
|
||||
--with-jvm-features=shenandoahgc \
|
||||
--with-version-pre= \
|
||||
--with-version-build="${JDK_BUILD_NUMBER}" \
|
||||
--with-version-opt=b${build_number} \
|
||||
--with-boot-jdk=${BOOT_JDK} \
|
||||
--enable-cds=yes \
|
||||
$REPRODUCIBLE_BUILD_OPTS \
|
||||
|| exit $?
|
||||
make clean CONF=linux-aarch64-server-release || exit $?
|
||||
make images CONF=linux-aarch64-server-release test-image || exit $?
|
||||
|
||||
JBSDK=${JBRSDK_BASE_NAME}-linux-aarch64-b${build_number}
|
||||
BASE_DIR=build/linux-aarch64-server-release/images
|
||||
JSDK=${BASE_DIR}/jdk
|
||||
JBRSDK_BUNDLE=jbrsdk
|
||||
|
||||
echo Fixing permissions
|
||||
chmod -R a+r $JSDK
|
||||
|
||||
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
|
||||
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
|
||||
|
||||
echo Creating $JBSDK.tar.gz ...
|
||||
sed 's/JBR/JBRSDK/g' ${BASE_DIR}/${JBRSDK_BUNDLE}/release > release
|
||||
mv release ${BASE_DIR}/${JBRSDK_BUNDLE}/release
|
||||
|
||||
# NB: --sort=name requires tar1.28
|
||||
tar $REPRODUCIBLE_TAR_OPTS --sort=name -pcf $JBSDK.tar \
|
||||
--exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man \
|
||||
-C $BASE_DIR ${JBRSDK_BUNDLE} || exit $?
|
||||
touch -c -d @$SOURCE_DATE_EPOCH $JBRSDK.tar
|
||||
gzip $JBSDK.tar || exit $?
|
||||
|
||||
JBR_BUNDLE=jbr
|
||||
JBR_BASE_NAME=jbr-$JBSDK_VERSION
|
||||
rm -rf $BASE_DIR/$JBR_BUNDLE
|
||||
|
||||
JBR=$JBR_BASE_NAME-linux-aarch64-b$build_number
|
||||
grep -v javafx modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.aarch64
|
||||
echo Running jlink....
|
||||
${JSDK}/bin/jlink \
|
||||
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
|
||||
--add-modules $(xargs < modules.list.aarch64 | sed s/" "//g | sed s/',$'//g) \
|
||||
--output ${BASE_DIR}/${JBR_BUNDLE} || exit $?
|
||||
|
||||
echo Modifying release info ...
|
||||
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${BASE_DIR}/${JBR_BUNDLE}/release
|
||||
|
||||
echo Creating $JBR.tar.gz ...
|
||||
tar $REPRODUCIBLE_TAR_OPTS --sort=name -pcf $JBR.tar -C $BASE_DIR ${JBR_BUNDLE} || exit $?
|
||||
touch -c -d @$SOURCE_DATE_EPOCH $JBR.tar
|
||||
gzip $JBR.tar || exit $?
|
||||
|
||||
JBRSDK_TEST=$JBRSDK_BASE_NAME-linux-test-aarch64-b$build_number
|
||||
echo Creating $JBRSDK_TEST.tar.gz ...
|
||||
tar -pcf $JBRSDK_TEST.tar -C $BASE_DIR --exclude='test/jdk/demos' test || exit $?
|
||||
gzip $JBRSDK_TEST.tar || exit $?
|
||||
162
jb/project/tools/linux/scripts/mkimages_x64.sh
Executable file
162
jb/project/tools/linux/scripts/mkimages_x64.sh
Executable file
@@ -0,0 +1,162 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# The following parameters must be specified:
|
||||
# JBSDK_VERSION - specifies major version of OpenJDK e.g. 11_0_6 (instead of dots '.' underbars "_" are used)
|
||||
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument to configure
|
||||
# build_number - specifies the number of JetBrainsRuntime build
|
||||
# bundle_type - specifies bundle to be built; possible values:
|
||||
# <empty> or nomod - the release bundles without any additional modules (jcef)
|
||||
# jcef - the release bundles with jcef
|
||||
# fd - the fastdebug bundles which also include the jcef module
|
||||
#
|
||||
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
#
|
||||
# $ ./java --version
|
||||
# openjdk 11.0.6 2020-01-14
|
||||
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
|
||||
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
|
||||
#
|
||||
# Environment variables:
|
||||
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
|
||||
# By default JCEF binaries should be located in ./jcef_linux_x64
|
||||
|
||||
while getopts ":i?" o; do
|
||||
case "${o}" in
|
||||
i)
|
||||
i="incremental build"
|
||||
INC_BUILD=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
JBSDK_VERSION=$1
|
||||
JDK_BUILD_NUMBER=$2
|
||||
build_number=$3
|
||||
bundle_type=$4
|
||||
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
|
||||
JCEF_PATH=${JCEF_PATH:=./jcef_linux_x64}
|
||||
|
||||
source jb/project/tools/common/scripts/common.sh
|
||||
|
||||
function do_configure {
|
||||
sh configure \
|
||||
$WITH_DEBUG_LEVEL \
|
||||
--with-vendor-name="$VENDOR_NAME" \
|
||||
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
|
||||
--with-jvm-features=shenandoahgc \
|
||||
--with-version-pre= \
|
||||
--with-version-build="$JDK_BUILD_NUMBER" \
|
||||
--with-version-opt=b"$build_number" \
|
||||
--with-boot-jdk="$BOOT_JDK" \
|
||||
--enable-cds=yes \
|
||||
$REPRODUCIBLE_BUILD_OPTS \
|
||||
|| do_exit $?
|
||||
}
|
||||
|
||||
function create_image_bundle {
|
||||
__bundle_name=$1
|
||||
__arch_name=$2
|
||||
__modules_path=$3
|
||||
__modules=$4
|
||||
|
||||
[ "$bundle_type" == "fd" ] && [ "$__arch_name" == "$JBRSDK_BUNDLE" ] && __bundle_name=$__arch_name && fastdebug_infix="fastdebug-"
|
||||
JBR=${__bundle_name}-${JBSDK_VERSION}-linux-x64-${fastdebug_infix}b${build_number}
|
||||
|
||||
echo Running jlink....
|
||||
[ -d "$IMAGES_DIR"/"$__arch_name" ] && rm -rf "${IMAGES_DIR:?}"/"$__arch_name"
|
||||
$JSDK/bin/jlink \
|
||||
--module-path "$__modules_path" --no-man-pages --compress=2 \
|
||||
--add-modules "$__modules" --output "$IMAGES_DIR"/"$__arch_name"
|
||||
|
||||
grep -v "^JAVA_VERSION" "$JSDK"/release | grep -v "^MODULES" >> "$IMAGES_DIR"/"$__arch_name"/release
|
||||
if [ "$__arch_name" == "$JBRSDK_BUNDLE" ]; then
|
||||
sed 's/JBR/JBRSDK/g' "$IMAGES_DIR"/"$__arch_name"/release > release
|
||||
mv release "$IMAGES_DIR"/"$__arch_name"/release
|
||||
copy_jmods "$__modules" "$__modules_path" "$IMAGES_DIR"/"$__arch_name"/jmods
|
||||
fi
|
||||
|
||||
# jmod does not preserve file permissions (JDK-8173610)
|
||||
[ -f "$IMAGES_DIR"/"$__arch_name"/lib/jcef_helper ] && chmod a+x "$IMAGES_DIR"/"$__arch_name"/lib/jcef_helper
|
||||
|
||||
echo Creating "$JBR".tar.gz ...
|
||||
|
||||
(cd "$IMAGES_DIR" &&
|
||||
find "$__arch_name" -print0 | LC_ALL=C sort -z | \
|
||||
tar $REPRODUCIBLE_TAR_OPTS \
|
||||
--no-recursion --null -T - -cf "$JBR".tar) || do_exit $?
|
||||
mv "$IMAGES_DIR"/"$JBR".tar ./"$JBR".tar
|
||||
[ -f "$JBR".tar.gz ] && rm "$JBR.tar.gz"
|
||||
touch -c -d "@$SOURCE_DATE_EPOCH" "$JBR".tar
|
||||
gzip "$JBR".tar || do_exit $?
|
||||
rm -rf "${IMAGES_DIR:?}"/"$__arch_name"
|
||||
}
|
||||
|
||||
WITH_DEBUG_LEVEL="--with-debug-level=release"
|
||||
RELEASE_NAME=linux-x86_64-server-release
|
||||
|
||||
case "$bundle_type" in
|
||||
"jcef")
|
||||
do_reset_changes=0
|
||||
;;
|
||||
"dcevm")
|
||||
HEAD_REVISION=$(git rev-parse HEAD)
|
||||
git am jb/project/tools/patches/dcevm/*.patch || do_exit $?
|
||||
do_reset_dcevm=0
|
||||
do_reset_changes=0
|
||||
;;
|
||||
"nomod" | "")
|
||||
bundle_type=""
|
||||
;;
|
||||
"fd")
|
||||
do_reset_changes=0
|
||||
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
|
||||
RELEASE_NAME=linux-x86_64-server-fastdebug
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$INC_BUILD" ]; then
|
||||
do_configure || do_exit $?
|
||||
make clean CONF=$RELEASE_NAME || do_exit $?
|
||||
fi
|
||||
make images CONF=$RELEASE_NAME || do_exit $?
|
||||
|
||||
IMAGES_DIR=build/$RELEASE_NAME/images
|
||||
JSDK=$IMAGES_DIR/jdk
|
||||
JSDK_MODS_DIR=$IMAGES_DIR/jmods
|
||||
JBRSDK_BUNDLE=jbrsdk
|
||||
|
||||
echo Fixing permissions
|
||||
chmod -R a+r $JSDK
|
||||
|
||||
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ]; then
|
||||
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
|
||||
update_jsdk_mods $JSDK $JCEF_PATH/jmods $JSDK/jmods $JSDK_MODS_DIR || do_exit $?
|
||||
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
|
||||
|
||||
jbr_name_postfix="_${bundle_type}"
|
||||
[ "$bundle_type" != "fd" ] && jbrsdk_name_postfix="_${bundle_type}"
|
||||
fi
|
||||
|
||||
# create runtime image bundle
|
||||
modules=$(xargs < modules.list | sed s/" "//g) || do_exit $?
|
||||
create_image_bundle "jbr${jbr_name_postfix}" "jbr" $JSDK_MODS_DIR "$modules" || do_exit $?
|
||||
|
||||
# create sdk image bundle
|
||||
modules=$(cat $JSDK/release | grep MODULES | sed s/MODULES=//g | sed s/' '/','/g | sed s/\"//g | sed s/\\n//g) || do_exit $?
|
||||
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
|
||||
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
|
||||
fi
|
||||
create_image_bundle "$JBRSDK_BUNDLE${jbr_name_postfix}" $JBRSDK_BUNDLE $JSDK_MODS_DIR "$modules" || do_exit $?
|
||||
|
||||
if [ -z "$bundle_type" ]; then
|
||||
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-linux-test-x64-b${build_number}
|
||||
echo Creating "$JBRSDK_TEST" ...
|
||||
make test-image CONF=$RELEASE_NAME || do_exit $?
|
||||
tar -pcf "$JBRSDK_TEST".tar -C $IMAGES_DIR --exclude='test/jdk/demos' test || do_exit $?
|
||||
[ -f "$JBRSDK_TEST.tar.gz" ] && rm "$JBRSDK_TEST.tar.gz"
|
||||
gzip "$JBRSDK_TEST".tar || do_exit $?
|
||||
fi
|
||||
|
||||
do_exit 0
|
||||
80
jb/project/tools/linux/scripts/mkimages_x86.sh
Executable file
80
jb/project/tools/linux/scripts/mkimages_x86.sh
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# The following parameters must be specified:
|
||||
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
|
||||
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
|
||||
# build_number - specifies the number of JetBrainsRuntime build
|
||||
#
|
||||
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
#
|
||||
# $ ./java --version
|
||||
# openjdk 11.0.6 2020-01-14
|
||||
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
|
||||
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
|
||||
#
|
||||
|
||||
JBSDK_VERSION=$1
|
||||
JDK_BUILD_NUMBER=$2
|
||||
build_number=$3
|
||||
|
||||
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
|
||||
|
||||
source jb/project/tools/common/scripts/common.sh
|
||||
|
||||
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
|
||||
|
||||
[ -z "$bundle_type" ] && (git apply -p0 < jb/project/tools/patches/exclude_jcef_module.patch || exit $?)
|
||||
|
||||
linux32 bash configure \
|
||||
--with-debug-level=release \
|
||||
--with-vendor-name="${VENDOR_NAME}" \
|
||||
--with-vendor-version-string="${VENDOR_VERSION_STRING}" \
|
||||
--with-version-pre= \
|
||||
--with-version-build=$JDK_BUILD_NUMBER \
|
||||
--with-version-opt=b${build_number} \
|
||||
--with-boot-jdk=${BOOT_JDK} \
|
||||
--enable-cds=yes || exit $?
|
||||
make clean CONF=linux-x86-server-release || exit $?
|
||||
make images CONF=linux-x86-server-release test-image || exit $?
|
||||
|
||||
JBSDK=${JBRSDK_BASE_NAME}-linux-x86-b${build_number}
|
||||
BASE_DIR=build/linux-x86-server-release/images
|
||||
JSDK=${BASE_DIR}/jdk
|
||||
JBRSDK_BUNDLE=jbrsdk
|
||||
|
||||
echo Fixing permissions
|
||||
chmod -R a+r $JSDK
|
||||
|
||||
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
|
||||
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
|
||||
|
||||
echo Creating $JBSDK.tar.gz ...
|
||||
sed 's/JBR/JBRSDK/g' ${BASE_DIR}/${JBRSDK_BUNDLE}/release > release
|
||||
mv release ${BASE_DIR}/${JBRSDK_BUNDLE}/release
|
||||
|
||||
tar -pcf $JBSDK.tar --exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man -C $BASE_DIR ${JBRSDK_BUNDLE} || exit $?
|
||||
gzip $JBSDK.tar || exit $?
|
||||
|
||||
JBR_BUNDLE=jbr
|
||||
JBR_BASE_NAME=jbr-$JBSDK_VERSION
|
||||
rm -rf $BASE_DIR/$JBR_BUNDLE
|
||||
|
||||
JBR=$JBR_BASE_NAME-linux-x86-b$build_number
|
||||
grep -v javafx modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.x86
|
||||
echo Running jlink....
|
||||
${JSDK}/bin/jlink \
|
||||
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
|
||||
--add-modules $(xargs < modules.list.x86 | sed s/" "//g | sed s/,$//g) --output ${BASE_DIR}/${JBR_BUNDLE} || exit $?
|
||||
|
||||
echo Modifying release info ...
|
||||
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${BASE_DIR}/${JBR_BUNDLE}/release
|
||||
|
||||
echo Creating $JBR.tar.gz ...
|
||||
tar -pcf $JBR.tar -C $BASE_DIR $JBR_BUNDLE || exit $?
|
||||
gzip $JBR.tar || exit $?
|
||||
|
||||
JBRSDK_TEST=$JBRSDK_BASE_NAME-linux-test-x86-b$build_number
|
||||
echo Creating $JBRSDK_TEST.tar.gz ...
|
||||
tar -pcf $JBRSDK_TEST.tar -C $BASE_DIR --exclude='test/jdk/demos' --exclude='test/hotspot/gtest' test || exit $?
|
||||
gzip $JBRSDK_TEST.tar || exit $?
|
||||
16
jb/project/tools/mac/scripts/entitlements.xml
Normal file
16
jb/project/tools/mac/scripts/entitlements.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-executable-page-protection</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
200
jb/project/tools/mac/scripts/mkimages.sh
Executable file
200
jb/project/tools/mac/scripts/mkimages.sh
Executable file
@@ -0,0 +1,200 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# The following parameters must be specified:
|
||||
# JBSDK_VERSION - specifies major version of OpenJDK e.g. 11_0_6 (instead of dots '.' underbars "_" are used)
|
||||
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument to configure
|
||||
# build_number - specifies the number of JetBrainsRuntime build
|
||||
# bundle_type - specifies bundle to be built; possible values:
|
||||
# <empty> or nomod - the release bundles without any additional modules (jcef)
|
||||
# jcef - the release bundles with jcef
|
||||
# fd - the fastdebug bundles which also include the jcef module
|
||||
#
|
||||
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
#
|
||||
# $ ./java --version
|
||||
# openjdk 11.0.6 2020-01-14
|
||||
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
|
||||
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
|
||||
#
|
||||
# Environment variables:
|
||||
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
|
||||
# By default JCEF binaries should be located in ./jcef_mac
|
||||
|
||||
while getopts ":i?" o; do
|
||||
case "${o}" in
|
||||
i)
|
||||
i="incremental build"
|
||||
INC_BUILD=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
JBSDK_VERSION=$1
|
||||
JDK_BUILD_NUMBER=$2
|
||||
build_number=$3
|
||||
bundle_type=$4
|
||||
architecture=$5 # aarch64 or x64
|
||||
enable_aot=$6 # temporary param for building test jre with aot under aarch64
|
||||
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
|
||||
WITH_IMPORT_MODULES="--with-import-modules=${MODULAR_SDK_PATH:=./modular-sdk}"
|
||||
JCEF_PATH=${JCEF_PATH:=./jcef_mac}
|
||||
architecture=${architecture:=x64}
|
||||
BOOT_JDK=${BOOT_JDK:=$(/usr/libexec/java_home -v 16)}
|
||||
|
||||
source jb/project/tools/common/scripts/common.sh
|
||||
|
||||
function do_configure {
|
||||
if [[ "${architecture}" == *aarch64* ]]; then
|
||||
sh configure \
|
||||
$WITH_DEBUG_LEVEL \
|
||||
--with-vendor-name="${VENDOR_NAME}" \
|
||||
--with-vendor-version-string="${VENDOR_VERSION_STRING}" \
|
||||
--with-macosx-bundle-name-base=${VENDOR_VERSION_STRING} \
|
||||
--with-macosx-bundle-id-base="com.jetbrains.jbr" \
|
||||
--with-jvm-features=shenandoahgc \
|
||||
--with-version-pre= \
|
||||
--with-version-build="${JDK_BUILD_NUMBER}" \
|
||||
--with-version-opt=b"${build_number}" \
|
||||
--with-boot-jdk="$BOOT_JDK" \
|
||||
--disable-hotspot-gtest --disable-javac-server --disable-full-docs --disable-manpages \
|
||||
--enable-cds=no \
|
||||
--with-extra-cflags="-F$(pwd)/Frameworks" \
|
||||
--with-extra-cxxflags="-F$(pwd)/Frameworks" \
|
||||
--with-extra-ldflags="-F$(pwd)/Frameworks" \
|
||||
$REPRODUCIBLE_BUILD_OPTS \
|
||||
|| do_exit $?
|
||||
else
|
||||
sh configure \
|
||||
$WITH_DEBUG_LEVEL \
|
||||
--with-vendor-name="$VENDOR_NAME" \
|
||||
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
|
||||
--with-macosx-bundle-name-base=${VENDOR_VERSION_STRING} \
|
||||
--with-macosx-bundle-id-base="com.jetbrains.jbr" \
|
||||
--with-jvm-features=shenandoahgc \
|
||||
--with-version-pre= \
|
||||
--with-version-build="$JDK_BUILD_NUMBER" \
|
||||
--with-version-opt=b"$build_number" \
|
||||
--with-boot-jdk="$BOOT_JDK" \
|
||||
--enable-cds=yes \
|
||||
$REPRODUCIBLE_BUILD_OPTS \
|
||||
|| do_exit $?
|
||||
fi
|
||||
}
|
||||
|
||||
function create_image_bundle {
|
||||
__bundle_name=$1
|
||||
__arch_name=$2
|
||||
__modules_path=$3
|
||||
__modules=$4
|
||||
|
||||
tmp=.bundle.$$.tmp
|
||||
mkdir "$tmp" || do_exit $?
|
||||
|
||||
[ "$bundle_type" == "fd" ] && [ "$__arch_name" == "$JBRSDK_BUNDLE" ] && __bundle_name=$__arch_name && fastdebug_infix="fastdebug-"
|
||||
JBR=${__bundle_name}-${JBSDK_VERSION}-osx-${architecture}-${fastdebug_infix}b${build_number}
|
||||
|
||||
JRE_CONTENTS=$tmp/$__arch_name/Contents
|
||||
mkdir -p "$JRE_CONTENTS" || do_exit $?
|
||||
|
||||
echo Running jlink...
|
||||
"$JSDK"/bin/jlink \
|
||||
--module-path "$__modules_path" --no-man-pages --compress=2 \
|
||||
--add-modules "$__modules" --output "$JRE_CONTENTS/Home" || do_exit $?
|
||||
|
||||
grep -v "^JAVA_VERSION" "$JSDK"/release | grep -v "^MODULES" >> "$JRE_CONTENTS/Home/release"
|
||||
if [ "$__arch_name" == "$JBRSDK_BUNDLE" ]; then
|
||||
sed 's/JBR/JBRSDK/g' $JRE_CONTENTS/Home/release > release
|
||||
mv release $JRE_CONTENTS/Home/release
|
||||
copy_jmods "$__modules" "$__modules_path" "$JRE_CONTENTS"/Home/jmods
|
||||
fi
|
||||
|
||||
cp -R "$JSDK"/../MacOS "$JRE_CONTENTS"
|
||||
cp "$JSDK"/../Info.plist "$JRE_CONTENTS"
|
||||
|
||||
[ -n "$bundle_type" ] && (cp -a $JCEF_PATH/Frameworks "$JRE_CONTENTS" || do_exit $?)
|
||||
|
||||
echo Creating "$JBR".tar.gz ...
|
||||
# Normalize timestamp
|
||||
find "$tmp"/"$__arch_name" -print0 | xargs -0 touch -c -h -t "$TOUCH_TIME"
|
||||
|
||||
(cd "$tmp" &&
|
||||
find "$__arch_name" -print0 | LC_ALL=C sort -z | \
|
||||
COPYFILE_DISABLE=1 tar $REPRODUCIBLE_TAR_OPTS --no-recursion --null -T - \
|
||||
-czf "$JBR".tar.gz --exclude='*.dSYM' --exclude='man') || do_exit $?
|
||||
mv "$tmp"/"$JBR".tar.gz "$JBR".tar.gz
|
||||
rm -rf "$tmp"
|
||||
}
|
||||
|
||||
WITH_DEBUG_LEVEL="--with-debug-level=release"
|
||||
CONF_ARCHITECTURE=x86_64
|
||||
if [[ "${architecture}" == *aarch64* ]]; then
|
||||
CONF_ARCHITECTURE=aarch64
|
||||
fi
|
||||
RELEASE_NAME=macosx-${CONF_ARCHITECTURE}-server-release
|
||||
|
||||
case "$bundle_type" in
|
||||
"jcef")
|
||||
do_reset_changes=0
|
||||
;;
|
||||
"dcevm")
|
||||
HEAD_REVISION=$(git rev-parse HEAD)
|
||||
git am jb/project/tools/patches/dcevm/*.patch || do_exit $?
|
||||
do_reset_dcevm=0
|
||||
do_reset_changes=0
|
||||
;;
|
||||
"nomod" | "")
|
||||
bundle_type=""
|
||||
;;
|
||||
"fd")
|
||||
do_reset_changes=0
|
||||
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
|
||||
RELEASE_NAME=macosx-${CONF_ARCHITECTURE}-server-fastdebug
|
||||
JBSDK=macosx-${architecture}-server-release
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$INC_BUILD" ]; then
|
||||
do_configure || do_exit $?
|
||||
make clean CONF=$RELEASE_NAME || do_exit $?
|
||||
fi
|
||||
make images CONF=$RELEASE_NAME || do_exit $?
|
||||
|
||||
IMAGES_DIR=build/$RELEASE_NAME/images
|
||||
|
||||
major_version=$(echo "$JBSDK_VERSION_WITH_DOTS" | awk -F "." '{print $1}')
|
||||
minor_version=$(echo "$JBSDK_VERSION_WITH_DOTS" | awk -F "." '{print $3}')
|
||||
[ -z "$minor_version" -o "$minor_version" = "0" ] && version_dir=$major_version || version_dir=$JBSDK_VERSION_WITH_DOTS
|
||||
JSDK=$IMAGES_DIR/jdk-bundle/jdk-$version_dir.jdk/Contents/Home
|
||||
JSDK_MODS_DIR=$IMAGES_DIR/jmods
|
||||
JBRSDK_BUNDLE=jbrsdk
|
||||
|
||||
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ]; then
|
||||
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
|
||||
update_jsdk_mods "$JSDK" "$JCEF_PATH"/jmods "$JSDK"/jmods "$JSDK_MODS_DIR" || do_exit $?
|
||||
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
|
||||
|
||||
jbr_name_postfix="_${bundle_type}"
|
||||
fi
|
||||
|
||||
# create runtime image bundle
|
||||
modules=$(xargs < modules.list | sed s/" "//g) || do_exit $?
|
||||
create_image_bundle "jbr${jbr_name_postfix}" "jbr" $JSDK_MODS_DIR "$modules" || do_exit $?
|
||||
|
||||
# create sdk image bundle
|
||||
modules=$(cat "$JSDK"/release | grep MODULES | sed s/MODULES=//g | sed s/' '/','/g | sed s/\"//g | sed s/\\n//g) || do_exit $?
|
||||
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
|
||||
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
|
||||
fi
|
||||
create_image_bundle "$JBRSDK_BUNDLE${jbr_name_postfix}" "$JBRSDK_BUNDLE" "$JSDK_MODS_DIR" "$modules" || do_exit $?
|
||||
|
||||
if [ -z "$bundle_type" ]; then
|
||||
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-osx-test-${architecture}-b${build_number}
|
||||
echo Creating "$JBRSDK_TEST" ...
|
||||
make test-image CONF=$RELEASE_NAME || do_exit $?
|
||||
[ -f "$JBRSDK_TEST.tar.gz" ] && rm "$JBRSDK_TEST.tar.gz"
|
||||
COPYFILE_DISABLE=1 tar -pczf "$JBRSDK_TEST".tar.gz -C $IMAGES_DIR --exclude='test/jdk/demos' test || do_exit $?
|
||||
fi
|
||||
|
||||
do_exit 0
|
||||
118
jb/project/tools/mac/scripts/notarize.sh
Executable file
118
jb/project/tools/mac/scripts/notarize.sh
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
APP_DIRECTORY=$1
|
||||
APPL_USER=$2
|
||||
APPL_PASSWORD=$3
|
||||
APP_NAME=$4
|
||||
BUNDLE_ID=$5
|
||||
FAKE_ROOT="${6:-fake-root}"
|
||||
|
||||
if [[ -z "$APP_DIRECTORY" ]] || [[ -z "$APPL_USER" ]] || [[ -z "$APPL_PASSWORD" ]]; then
|
||||
echo "Usage: $0 AppDirectory Username Password"
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -d "$APP_DIRECTORY" ]]; then
|
||||
echo "AppDirectory '$APP_DIRECTORY' does not exist or not a directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function log() {
|
||||
echo "$(date '+[%H:%M:%S]') $*"
|
||||
}
|
||||
|
||||
function publish-log() {
|
||||
id=$1
|
||||
file=$2
|
||||
curl -T "$file" "$ARTIFACTORY_URL/$id" || true
|
||||
}
|
||||
|
||||
function altool-upload() {
|
||||
# Since altool uses same file for upload token we have to trick it into using different folders for token file location
|
||||
# Also it copies zip into TMPDIR so we override it too, to simplify cleanup
|
||||
OLD_HOME="$HOME"
|
||||
export HOME="$FAKE_ROOT/home"
|
||||
export TMPDIR="$FAKE_ROOT/tmp"
|
||||
mkdir -p "$HOME"
|
||||
mkdir -p "$TMPDIR"
|
||||
export _JAVA_OPTIONS="-Duser.home=$HOME -Djava.io.tmpdir=$TMPDIR"
|
||||
# Reduce amount of downloads, cache transporter libraries
|
||||
shared_itmstransporter="$OLD_HOME/shared-itmstransporter"
|
||||
if [[ -f "$shared_itmstransporter" ]]; then
|
||||
cp -r "$shared_itmstransporter" "$HOME/.itmstransporter"
|
||||
fi
|
||||
# For some reason altool prints everything to stderr, not stdout
|
||||
set +e
|
||||
xcrun altool --notarize-app \
|
||||
--username "$APPL_USER" --password "$APPL_PASSWORD" \
|
||||
--primary-bundle-id "$BUNDLE_ID" \
|
||||
--asc-provider JetBrainssro --file "$1" 2>&1 | tee "altool.init.out"
|
||||
unset TMPDIR
|
||||
export HOME="$OLD_HOME"
|
||||
set -e
|
||||
}
|
||||
|
||||
#immediately exit script with an error if a command fails
|
||||
set -euo pipefail
|
||||
|
||||
#file="$APP_NAME.zip"
|
||||
|
||||
#log "Zipping $file..."
|
||||
#rm -rf "$file"
|
||||
#ditto -c -k --sequesterRsrc --keepParent "$APP_DIRECTORY" "$file"
|
||||
|
||||
log "Notarizing $APP_NAME..."
|
||||
rm -rf "altool.init.out" "altool.check.out"
|
||||
altool-upload "$APP_NAME"
|
||||
|
||||
notarization_info="$(grep -e "RequestUUID" "altool.init.out" | grep -oE '([0-9a-f-]{36})')"
|
||||
|
||||
if [ -z "$notarization_info" ]; then
|
||||
log "Faile to read RequestUUID from altool.init.out"
|
||||
exit 10
|
||||
fi
|
||||
|
||||
PATH="$PATH:/usr/local/bin/"
|
||||
|
||||
log "Notarization request sent, awaiting response"
|
||||
spent=0
|
||||
|
||||
while true; do
|
||||
# For some reason altool prints everything to stderr, not stdout
|
||||
xcrun altool --username "$APPL_USER" --notarization-info "$notarization_info" --password "$APPL_PASSWORD" >"altool.check.out" 2>&1 || true
|
||||
status="$(grep -oe 'Status: .*' "altool.check.out" | cut -c 9- || true)"
|
||||
log "Current status: $status"
|
||||
if [ "$status" = "invalid" ]; then
|
||||
log "Notarization failed"
|
||||
ec=1
|
||||
elif [ "$status" = "success" ]; then
|
||||
log "Notarization succeeded"
|
||||
ec=0
|
||||
else
|
||||
if [ "$status" != "in progress" ]; then
|
||||
log "Unknown notarization status, waiting more, altool output:"
|
||||
cat "altool.check.out"
|
||||
fi
|
||||
if [[ $spent -gt 60 ]]; then
|
||||
log "Waiting time out (apx 60 minutes)"
|
||||
ec=2
|
||||
break
|
||||
fi
|
||||
sleep 60
|
||||
((spent += 1))
|
||||
continue
|
||||
fi
|
||||
developer_log="developer_log.json"
|
||||
log "Fetching $developer_log"
|
||||
# TODO: Replace cut with trim or something better
|
||||
url="$(grep -oe 'LogFileURL: .*' "altool.check.out" | cut -c 13-)"
|
||||
wget "$url" -O "$developer_log" && cat "$developer_log" || true
|
||||
if [ $ec != 0 ]; then
|
||||
log "Publishing $developer_log"
|
||||
publish-log "$notarization_info" "$developer_log"
|
||||
fi
|
||||
break
|
||||
done
|
||||
cat "altool.check.out"
|
||||
|
||||
rm -rf "altool.init.out" "altool.check.out"
|
||||
exit $ec
|
||||
111
jb/project/tools/mac/scripts/sign.sh
Executable file
111
jb/project/tools/mac/scripts/sign.sh
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
APPLICATION_PATH=$1
|
||||
APP_NAME=$2
|
||||
BUNDLE_ID=$3
|
||||
JB_DEVELOPER_CERT=$4
|
||||
JB_INSTALLER_CERT=$5
|
||||
|
||||
if [[ -z "$APPLICATION_PATH" ]] || [[ -z "$JB_DEVELOPER_CERT" ]]; then
|
||||
echo "Usage: $0 AppDirectory CertificateID"
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -d "$APPLICATION_PATH" ]]; then
|
||||
echo "AppDirectory '$APPLICATION_PATH' does not exist or not a directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function log() {
|
||||
echo "$(date '+[%H:%M:%S]') $*"
|
||||
}
|
||||
|
||||
#immediately exit script with an error if a command fails
|
||||
set -euo pipefail
|
||||
|
||||
# Cleanup files left from previous sign attempt (if any)
|
||||
find "$APPLICATION_PATH" -name '*.cstemp' -exec rm '{}' \;
|
||||
|
||||
log "Signing libraries and executables..."
|
||||
# -perm +111 searches for executables
|
||||
for f in \
|
||||
"Contents/Home/lib" "Contents/MacOS" \
|
||||
"Contents/Home/Frameworks" \
|
||||
"Contents/Frameworks"; do
|
||||
if [ -d "$APPLICATION_PATH/$f" ]; then
|
||||
find "$APPLICATION_PATH/$f" \
|
||||
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -name "*.tbd" -o -name "*.node" -o -perm +111 \) \
|
||||
-exec codesign --timestamp \
|
||||
-v -s "$JB_DEVELOPER_CERT" --options=runtime --force \
|
||||
--entitlements entitlements.xml {} \;
|
||||
fi
|
||||
done
|
||||
|
||||
log "Signing libraries in jars in $PWD"
|
||||
|
||||
# todo: add set -euo pipefail; into the inner sh -c
|
||||
# `-e` prevents `grep -q && printf` loginc
|
||||
# with `-o pipefail` there's no input for 'while' loop
|
||||
find "$APPLICATION_PATH" -name '*.jar' \
|
||||
-exec sh -c "set -u; unzip -l \"\$0\" | grep -q -e '\.dylib\$' -e '\.jnilib\$' -e '\.so\$' -e '\.tbd\$' -e '^jattach\$' && printf \"\$0\0\" " {} \; |
|
||||
while IFS= read -r -d $'\0' file; do
|
||||
log "Processing libraries in $file"
|
||||
|
||||
rm -rf jarfolder jar.jar
|
||||
mkdir jarfolder
|
||||
filename="${file##*/}"
|
||||
log "Filename: $filename"
|
||||
cp "$file" jarfolder && (cd jarfolder && jar xf "$filename" && rm "$filename")
|
||||
|
||||
find jarfolder \
|
||||
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -name "*.tbd" -o -name "jattach" \) \
|
||||
-exec codesign --timestamp \
|
||||
--force \
|
||||
-v -s "$JB_DEVELOPER_CERT" --options=runtime \
|
||||
--entitlements entitlements.xml {} \;
|
||||
|
||||
(cd jarfolder; zip -q -r -o -0 ../jar.jar .)
|
||||
mv jar.jar "$file"
|
||||
done
|
||||
|
||||
rm -rf jarfolder jar.jar
|
||||
|
||||
log "Signing other files..."
|
||||
for f in \
|
||||
"Contents/Home/bin"; do
|
||||
if [ -d "$APPLICATION_PATH/$f" ]; then
|
||||
find "$APPLICATION_PATH/$f" \
|
||||
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -name "*.tbd" -o -perm +111 \) \
|
||||
-exec codesign --timestamp \
|
||||
-v -s "$JB_DEVELOPER_CERT" --options=runtime --force \
|
||||
--entitlements entitlements.xml {} \;
|
||||
fi
|
||||
done
|
||||
|
||||
#log "Signing executable..."
|
||||
#codesign --timestamp \
|
||||
# -v -s "$JB_DEVELOPER_CERT" --options=runtime \
|
||||
# --force \
|
||||
# --entitlements entitlements.xml "$APPLICATION_PATH/Contents/MacOS/idea"
|
||||
|
||||
log "Signing whole app..."
|
||||
codesign --timestamp \
|
||||
-v -s "$JB_DEVELOPER_CERT" --options=runtime \
|
||||
--force \
|
||||
--entitlements entitlements.xml "$APPLICATION_PATH"
|
||||
|
||||
BUILD_NAME=$(echo $APPLICATION_PATH | awk -F"/" '{ print $2 }')
|
||||
|
||||
log "Creating $APP_NAME.pkg..."
|
||||
rm -rf "$APP_NAME.pkg"
|
||||
pkgbuild --identifier $BUNDLE_ID --sign "$JB_INSTALLER_CERT" --root $APPLICATION_PATH \
|
||||
--install-location /Library/Java/JavaVirtualMachines/${BUILD_NAME} ${APP_NAME}.pkg
|
||||
|
||||
#log "Signing whole app..."
|
||||
#codesign --timestamp \
|
||||
# -v -s "$JB_DEVELOPER_CERT" --options=runtime \
|
||||
# --force \
|
||||
# --entitlements entitlements.xml $APP_NAME.pkg
|
||||
|
||||
log "Verifying java is not broken"
|
||||
find "$APPLICATION_PATH" \
|
||||
-type f -name 'java' -perm +111 -exec {} -version \;
|
||||
138
jb/project/tools/mac/scripts/signapp.sh
Executable file
138
jb/project/tools/mac/scripts/signapp.sh
Executable file
@@ -0,0 +1,138 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
#immediately exit script with an error if a command fails
|
||||
set -euo pipefail
|
||||
|
||||
export COPY_EXTENDED_ATTRIBUTES_DISABLE=true
|
||||
export COPYFILE_DISABLE=true
|
||||
|
||||
INPUT_FILE=$1
|
||||
EXPLODED=$2.exploded
|
||||
BACKUP_JMODS=$2.backup
|
||||
USERNAME=$3
|
||||
PASSWORD=$4
|
||||
CODESIGN_STRING=$5
|
||||
JB_INSTALLER_CERT=$6
|
||||
NOTARIZE=$7
|
||||
BUNDLE_ID=$8
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
function log() {
|
||||
echo "$(date '+[%H:%M:%S]') $*"
|
||||
}
|
||||
|
||||
log "Deleting $EXPLODED ..."
|
||||
if test -d "$EXPLODED"; then
|
||||
find "$EXPLODED" -mindepth 1 -maxdepth 1 -exec chmod -R u+wx '{}' \;
|
||||
fi
|
||||
rm -rf "$EXPLODED"
|
||||
mkdir "$EXPLODED"
|
||||
rm -rf "$BACKUP_JMODS"
|
||||
mkdir "$BACKUP_JMODS"
|
||||
|
||||
log "Unzipping $INPUT_FILE to $EXPLODED ..."
|
||||
tar -xzvf "$INPUT_FILE" --directory $EXPLODED
|
||||
BUILD_NAME="$(ls "$EXPLODED")"
|
||||
#sed -i '' s/BNDL/APPL/ $EXPLODED/$BUILD_NAME/Contents/Info.plist
|
||||
rm -f $EXPLODED/$BUILD_NAME/Contents/CodeResources
|
||||
rm "$INPUT_FILE"
|
||||
if test -d $EXPLODED/$BUILD_NAME/Contents/Home/jmods; then
|
||||
mv $EXPLODED/$BUILD_NAME/Contents/Home/jmods $BACKUP_JMODS
|
||||
fi
|
||||
|
||||
log "$INPUT_FILE extracted and removed"
|
||||
|
||||
APP_NAME=$(echo ${INPUT_FILE} | awk -F".tar" '{ print $1 }')
|
||||
APPLICATION_PATH=$(sed "s/osx-//" <<< "$EXPLODED/$APP_NAME")
|
||||
mv $EXPLODED/$BUILD_NAME $APPLICATION_PATH
|
||||
|
||||
find "$APPLICATION_PATH/Contents/Home/bin" \
|
||||
-maxdepth 1 -type f -name '*.jnilib' -print0 |
|
||||
while IFS= read -r -d $'\0' file; do
|
||||
if [ -f "$file" ]; then
|
||||
log "Linking $file"
|
||||
b="$(basename "$file" .jnilib)"
|
||||
ln -sf "$b.jnilib" "$(dirname "$file")/$b.dylib"
|
||||
fi
|
||||
done
|
||||
|
||||
find "$APPLICATION_PATH/Contents/" \
|
||||
-maxdepth 1 -type f -name '*.txt' -print0 |
|
||||
while IFS= read -r -d $'\0' file; do
|
||||
if [ -f "$file" ]; then
|
||||
log "Moving $file"
|
||||
mv "$file" "$APPLICATION_PATH/Contents/Resources"
|
||||
fi
|
||||
done
|
||||
|
||||
non_plist=$(find "$APPLICATION_PATH/Contents/" -maxdepth 1 -type f -and -not -name 'Info.plist' | wc -l)
|
||||
if [[ $non_plist -gt 0 ]]; then
|
||||
log "Only Info.plist file is allowed in Contents directory but found $non_plist file(s):"
|
||||
log "$(find "$APPLICATION_PATH/Contents/" -maxdepth 1 -type f -and -not -name 'Info.plist')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Unlocking keychain..."
|
||||
# Make sure *.p12 is imported into local KeyChain
|
||||
security unlock-keychain -p "$PASSWORD" "/Users/$USERNAME/Library/Keychains/login.keychain"
|
||||
|
||||
attempt=1
|
||||
limit=3
|
||||
set +e
|
||||
while [[ $attempt -le $limit ]]; do
|
||||
log "Signing (attempt $attempt) $APPLICATION_PATH ..."
|
||||
./sign.sh "$APPLICATION_PATH" "$APP_NAME" "$BUNDLE_ID" "$CODESIGN_STRING" "$JB_INSTALLER_CERT"
|
||||
ec=$?
|
||||
if [[ $ec -ne 0 ]]; then
|
||||
((attempt += 1))
|
||||
if [ $attempt -eq $limit ]; then
|
||||
set -e
|
||||
fi
|
||||
log "Signing failed, wait for 30 sec and try to sign again"
|
||||
sleep 30
|
||||
else
|
||||
log "Signing done"
|
||||
codesign -v "$APPLICATION_PATH" -vvvvv
|
||||
log "Check sign done"
|
||||
spctl -a -v $APPLICATION_PATH
|
||||
((attempt += limit))
|
||||
fi
|
||||
done
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$NOTARIZE" = "yes" ]; then
|
||||
log "Notarizing..."
|
||||
# shellcheck disable=SC1090
|
||||
source "$HOME/.notarize_token"
|
||||
# Since notarization tool uses same file for upload token we have to trick it into using different folders, hence fake root
|
||||
# Also it leaves copy of zip file in TMPDIR, so notarize.sh overrides it and uses FAKE_ROOT as location for temp TMPDIR
|
||||
FAKE_ROOT="$(pwd)/fake-root"
|
||||
mkdir -p "$FAKE_ROOT"
|
||||
echo "Notarization will use fake root: $FAKE_ROOT"
|
||||
./notarize.sh "$APPLICATION_PATH" "$APPLE_USERNAME" "$APPLE_PASSWORD" "$APP_NAME.pkg" "$BUNDLE_ID" "$FAKE_ROOT"
|
||||
rm -rf "$FAKE_ROOT"
|
||||
|
||||
set +e
|
||||
log "Stapling..."
|
||||
xcrun stapler staple "$APPLICATION_PATH"
|
||||
else
|
||||
log "Notarization disabled"
|
||||
log "Stapling disabled"
|
||||
fi
|
||||
|
||||
log "Zipping $BUILD_NAME to $INPUT_FILE ..."
|
||||
(
|
||||
#cd "$EXPLODED"
|
||||
#ditto -c -k --sequesterRsrc --keepParent "$BUILD_NAME" "../$INPUT_FILE"
|
||||
if test -d $BACKUP_JMODS/jmods; then
|
||||
mv $BACKUP_JMODS/jmods $APPLICATION_PATH/Contents/Home
|
||||
fi
|
||||
mv $APPLICATION_PATH $EXPLODED/$BUILD_NAME
|
||||
|
||||
tar -pczvf $INPUT_FILE --exclude='man' -C $EXPLODED $BUILD_NAME
|
||||
log "Finished zipping"
|
||||
)
|
||||
rm -rf "$EXPLODED"
|
||||
log "Done"
|
||||
30
jb/project/tools/patches/add_jcef_module.patch
Normal file
30
jb/project/tools/patches/add_jcef_module.patch
Normal file
@@ -0,0 +1,30 @@
|
||||
diff --git modules.list modules.list
|
||||
index 054f21d1ee0..d9a121f0273 100644
|
||||
--- modules.list
|
||||
+++ modules.list
|
||||
@@ -49,4 +49,7 @@ jdk.unsupported,
|
||||
jdk.xml.dom,
|
||||
jdk.zipfs,
|
||||
jdk.hotspot.agent,
|
||||
-jdk.jcmd
|
||||
+jdk.jcmd,
|
||||
+jcef,
|
||||
+gluegen.rt,
|
||||
+jogl.all
|
||||
diff --git src/java.desktop/share/classes/module-info.java src/java.desktop/share/classes/module-info.java
|
||||
index 897647ee368..781d1809493 100644
|
||||
--- src/java.desktop/share/classes/module-info.java
|
||||
+++ src/java.desktop/share/classes/module-info.java
|
||||
@@ -116,7 +116,11 @@ module java.desktop {
|
||||
// see make/GensrcModuleInfo.gmk
|
||||
exports sun.awt to
|
||||
jdk.accessibility,
|
||||
- jdk.unsupported.desktop;
|
||||
+ jdk.unsupported.desktop,
|
||||
+ jcef,
|
||||
+ jogl.all;
|
||||
+
|
||||
+ exports java.awt.peer to jcef;
|
||||
|
||||
exports java.awt.dnd.peer to jdk.unsupported.desktop;
|
||||
exports sun.awt.dnd to jdk.unsupported.desktop;
|
||||
8853
jb/project/tools/patches/dcevm/0001-Apply-basic-dcevm11-patch.patch
Normal file
8853
jb/project/tools/patches/dcevm/0001-Apply-basic-dcevm11-patch.patch
Normal file
File diff suppressed because it is too large
Load Diff
1569
jb/project/tools/patches/dcevm/0002-dcevm11-fixes.patch
Normal file
1569
jb/project/tools/patches/dcevm/0002-dcevm11-fixes.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
From 960dafbeeba190911955c208b611fecc15d66738 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Wed, 11 Mar 2020 14:19:34 +0100
|
||||
Subject: [PATCH 03/34] Fix class cast exception on redefinition of class A,
|
||||
that is superclass of B that has anonymous class C
|
||||
|
||||
---
|
||||
src/hotspot/share/oops/instanceKlass.cpp | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
|
||||
index 994fc8a3bc8..3be3a09ef8f 100644
|
||||
--- a/src/hotspot/share/oops/instanceKlass.cpp
|
||||
+++ b/src/hotspot/share/oops/instanceKlass.cpp
|
||||
@@ -953,7 +953,10 @@ bool InstanceKlass::link_class_impl(TRAPS) {
|
||||
|
||||
if (!is_linked()) {
|
||||
if (!is_rewritten()) {
|
||||
- {
|
||||
+ // (DCEVM): If class A is being redefined and class B->A (B is extended from A) and B is host class of anonymous class C
|
||||
+ // then second redefinition fails with cannot cast klass exception. So we currently turn off bytecode verification
|
||||
+ // on redefinition.
|
||||
+ if (!AllowEnhancedClassRedefinition || !newest_version()->is_redefining()) {
|
||||
bool verify_ok = verify_code(THREAD);
|
||||
if (!verify_ok) {
|
||||
return false;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
1086
jb/project/tools/patches/dcevm/0004-HotswapAgent-integration.patch
Normal file
1086
jb/project/tools/patches/dcevm/0004-HotswapAgent-integration.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,240 @@
|
||||
From 39df5f163d4a0f1fd6b92313a5570808f19d5e20 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 4 Oct 2020 21:12:12 +0200
|
||||
Subject: [PATCH 05/34] Support for Lambda class redefinition
|
||||
|
||||
---
|
||||
.../share/classfile/classLoaderData.cpp | 9 +++
|
||||
.../share/classfile/classLoaderData.hpp | 2 +-
|
||||
.../share/classfile/systemDictionary.cpp | 12 +++-
|
||||
.../share/classfile/systemDictionary.hpp | 1 +
|
||||
.../prims/jvmtiEnhancedRedefineClasses.cpp | 65 +++++++++++++++++--
|
||||
.../prims/jvmtiEnhancedRedefineClasses.hpp | 1 +
|
||||
.../share/prims/resolvedMethodTable.cpp | 2 +
|
||||
src/hotspot/share/prims/unsafe.cpp | 1 +
|
||||
8 files changed, 83 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
|
||||
index 0cd90bb8c27..4d64c6b454a 100644
|
||||
--- a/src/hotspot/share/classfile/classLoaderData.cpp
|
||||
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
|
||||
@@ -593,6 +593,15 @@ Dictionary* ClassLoaderData::create_dictionary() {
|
||||
return new Dictionary(this, size, resizable);
|
||||
}
|
||||
|
||||
+void ClassLoaderData::exchange_holders(ClassLoaderData* cld) {
|
||||
+ oop holder_oop = _holder.peek();
|
||||
+ _holder.replace(cld->_holder.peek());
|
||||
+ cld->_holder.replace(holder_oop);
|
||||
+ WeakHandle<vm_class_loader_data> exchange = _holder;
|
||||
+ _holder = cld->_holder;
|
||||
+ cld->_holder = exchange;
|
||||
+}
|
||||
+
|
||||
// Tell the GC to keep this klass alive while iterating ClassLoaderDataGraph
|
||||
oop ClassLoaderData::holder_phantom() const {
|
||||
// A klass that was previously considered dead can be looked up in the
|
||||
diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp
|
||||
index ba2393f8dd0..e2ae0a77351 100644
|
||||
--- a/src/hotspot/share/classfile/classLoaderData.hpp
|
||||
+++ b/src/hotspot/share/classfile/classLoaderData.hpp
|
||||
@@ -181,7 +181,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
bool has_accumulated_modified_oops() { return _accumulated_modified_oops; }
|
||||
oop holder_no_keepalive() const;
|
||||
oop holder_phantom() const;
|
||||
-
|
||||
+ void exchange_holders(ClassLoaderData* cld);
|
||||
private:
|
||||
void unload();
|
||||
bool keep_alive() const { return _keep_alive > 0; }
|
||||
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
|
||||
index bd0cae7cb9b..8f2b46add4d 100644
|
||||
--- a/src/hotspot/share/classfile/systemDictionary.cpp
|
||||
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
|
||||
@@ -1062,10 +1062,14 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
|
||||
Handle class_loader,
|
||||
ClassFileStream* st,
|
||||
const ClassLoadInfo& cl_info,
|
||||
+ InstanceKlass* old_klass,
|
||||
TRAPS) {
|
||||
|
||||
EventClassLoad class_load_start_event;
|
||||
ClassLoaderData* loader_data;
|
||||
+
|
||||
+ bool is_redefining = (old_klass != NULL);
|
||||
+
|
||||
bool is_unsafe_anon_class = cl_info.unsafe_anonymous_host() != NULL;
|
||||
|
||||
// - for unsafe anonymous class: create a new CLD whith a class holder that uses
|
||||
@@ -1094,8 +1098,12 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
|
||||
class_name,
|
||||
loader_data,
|
||||
cl_info,
|
||||
- false, // pick_newest
|
||||
+ is_redefining, // pick_newest
|
||||
CHECK_NULL);
|
||||
+ if (is_redefining && k != NULL) {
|
||||
+ k->set_redefining(true);
|
||||
+ k->set_old_version(old_klass);
|
||||
+ }
|
||||
|
||||
if ((cl_info.is_hidden() || is_unsafe_anon_class) && k != NULL) {
|
||||
// Hidden classes that are not strong and unsafe anonymous classes must update
|
||||
@@ -1998,7 +2006,7 @@ void SystemDictionary::remove_from_hierarchy(InstanceKlass* k) {
|
||||
k->remove_from_sibling_list();
|
||||
}
|
||||
|
||||
-// (DCEVM)
|
||||
+// (DCEVM)
|
||||
void SystemDictionary::update_constraints_after_redefinition() {
|
||||
constraints()->update_after_redefinition();
|
||||
}
|
||||
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp
|
||||
index 4547449dbec..931e655d631 100644
|
||||
--- a/src/hotspot/share/classfile/systemDictionary.hpp
|
||||
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
|
||||
@@ -329,6 +329,7 @@ public:
|
||||
Handle class_loader,
|
||||
ClassFileStream* st,
|
||||
const ClassLoadInfo& cl_info,
|
||||
+ InstanceKlass* old_klass,
|
||||
TRAPS);
|
||||
|
||||
// Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index 92ce6c27b8a..8b765623dcd 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -494,6 +494,8 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
|
||||
|
||||
|
||||
+ // SystemDictionary::methods_do(fix_invoke_method);
|
||||
+
|
||||
// JSR-292 support
|
||||
if (_any_class_has_resolved_methods) {
|
||||
bool trace_name_printed = false;
|
||||
@@ -756,12 +758,34 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
// load hook event.
|
||||
state->set_class_being_redefined(the_class, _class_load_kind);
|
||||
|
||||
- InstanceKlass* k = SystemDictionary::resolve_from_stream(the_class_sym,
|
||||
- the_class_loader,
|
||||
- protection_domain,
|
||||
- &st,
|
||||
- the_class,
|
||||
- THREAD);
|
||||
+ InstanceKlass* k;
|
||||
+
|
||||
+ if (InstanceKlass::cast(the_class)->is_anonymous()) {
|
||||
+ const InstanceKlass* host_class = the_class->host_klass();
|
||||
+
|
||||
+ // Make sure it's the real host class, not another anonymous class.
|
||||
+ while (host_class != NULL && host_class->is_anonymous()) {
|
||||
+ host_class = host_class->host_klass();
|
||||
+ }
|
||||
+
|
||||
+ k = SystemDictionary::parse_stream(the_class_sym,
|
||||
+ the_class_loader,
|
||||
+ protection_domain,
|
||||
+ &st,
|
||||
+ host_class,
|
||||
+ the_class,
|
||||
+ NULL,
|
||||
+ THREAD);
|
||||
+ k->class_loader_data()->exchange_holders(the_class->class_loader_data());
|
||||
+ the_class->class_loader_data()->inc_keep_alive();
|
||||
+ } else {
|
||||
+ k = SystemDictionary::resolve_from_stream(the_class_sym,
|
||||
+ the_class_loader,
|
||||
+ protection_domain,
|
||||
+ &st,
|
||||
+ the_class,
|
||||
+ THREAD);
|
||||
+ }
|
||||
// Clear class_being_redefined just to be sure.
|
||||
state->clear_class_being_redefined();
|
||||
|
||||
@@ -1442,6 +1466,30 @@ void VM_EnhancedRedefineClasses::MethodDataCleaner::do_klass(Klass* k) {
|
||||
}
|
||||
}
|
||||
|
||||
+void VM_EnhancedRedefineClasses::fix_invoke_method(Method* method) {
|
||||
+
|
||||
+ constantPoolHandle other_cp = constantPoolHandle(method->constants());
|
||||
+
|
||||
+ for (int i = 0; i < other_cp->length(); i++) {
|
||||
+ if (other_cp->tag_at(i).is_klass()) {
|
||||
+ Klass* klass = other_cp->resolved_klass_at(i);
|
||||
+ if (klass->new_version() != NULL) {
|
||||
+ // Constant pool entry points to redefined class -- update to the new version
|
||||
+ other_cp->klass_at_put(i, klass->newest_version());
|
||||
+ }
|
||||
+ assert(other_cp->resolved_klass_at(i)->new_version() == NULL, "Must be new klass!");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ConstantPoolCache* cp_cache = other_cp->cache();
|
||||
+ if (cp_cache != NULL) {
|
||||
+ cp_cache->clear_entries();
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+
|
||||
+
|
||||
void VM_EnhancedRedefineClasses::update_jmethod_ids() {
|
||||
for (int j = 0; j < _matching_methods_length; ++j) {
|
||||
Method* old_method = _matching_old_methods[j];
|
||||
@@ -1979,7 +2027,10 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
|
||||
// Find classes not directly redefined, but affected by a redefinition (because one of its supertypes is redefined)
|
||||
AffectedKlassClosure closure(_affected_klasses);
|
||||
// Updated in j10, from original SystemDictionary::classes_do
|
||||
- ClassLoaderDataGraph::dictionary_classes_do(&closure);
|
||||
+
|
||||
+ ClassLoaderDataGraph::classes_do(&closure);
|
||||
+ //ClassLoaderDataGraph::dictionary_classes_do(&closure);
|
||||
+
|
||||
log_trace(redefine, class, load)("%d classes affected", _affected_klasses->length());
|
||||
|
||||
// Sort the affected klasses such that a supertype is always on a smaller array index than its subtype.
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
index 60b62c3170a..d8a11b51fe9 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
@@ -116,6 +116,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
void rollback();
|
||||
static void mark_as_scavengable(nmethod* nm);
|
||||
static void unpatch_bytecode(Method* method);
|
||||
+ static void fix_invoke_method(Method* method);
|
||||
|
||||
// Figure out which new methods match old methods in name and signature,
|
||||
// which methods have been added, and which are no longer present
|
||||
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
index 122bb8c186b..81b3aa96564 100644
|
||||
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
@@ -414,6 +414,8 @@ void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed)
|
||||
InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
|
||||
Method* newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
|
||||
|
||||
+ log_info(redefine, class, load, exceptions)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
|
||||
+
|
||||
assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
|
||||
assert(newer_method != NULL, "method_with_idnum() should not be NULL");
|
||||
assert(old_method != newer_method, "sanity check");
|
||||
diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp
|
||||
index 72d81ec9d6c..027afa3fabd 100644
|
||||
--- a/src/hotspot/share/prims/unsafe.cpp
|
||||
+++ b/src/hotspot/share/prims/unsafe.cpp
|
||||
@@ -865,6 +865,7 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
|
||||
host_loader,
|
||||
&st,
|
||||
cl_info,
|
||||
+ NULL,
|
||||
CHECK_NULL);
|
||||
if (anonk == NULL) {
|
||||
return NULL;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
From 5af1daedc86b5fec0f222cbdda3afbdf518985ea Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sat, 23 May 2020 10:02:15 +0200
|
||||
Subject: [PATCH 06/34] Fix "no original bytecode found" error if method with
|
||||
bkp is missing
|
||||
|
||||
Sometimes IDE can deploy class with erroneous method, such method has
|
||||
n bytecode, but breakpoint position can still exist.
|
||||
---
|
||||
src/hotspot/share/interpreter/bytecodes.cpp | 2 +-
|
||||
.../share/interpreter/interpreterRuntime.cpp | 2 +-
|
||||
src/hotspot/share/oops/method.cpp | 8 ++++----
|
||||
src/hotspot/share/oops/method.hpp | 4 ++--
|
||||
.../prims/jvmtiEnhancedRedefineClasses.cpp | 18 ++++++++++--------
|
||||
5 files changed, 18 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/interpreter/bytecodes.cpp b/src/hotspot/share/interpreter/bytecodes.cpp
|
||||
index e377e36b88c..262ecc021b2 100644
|
||||
--- a/src/hotspot/share/interpreter/bytecodes.cpp
|
||||
+++ b/src/hotspot/share/interpreter/bytecodes.cpp
|
||||
@@ -84,7 +84,7 @@ Bytecodes::Code Bytecodes::code_at(Method* method, int bci) {
|
||||
Bytecodes::Code Bytecodes::non_breakpoint_code_at(const Method* method, address bcp) {
|
||||
assert(method != NULL, "must have the method for breakpoint conversion");
|
||||
assert(method->contains(bcp), "must be valid bcp in method");
|
||||
- return method->orig_bytecode_at(method->bci_from(bcp));
|
||||
+ return method->orig_bytecode_at(method->bci_from(bcp), false);
|
||||
}
|
||||
|
||||
int Bytecodes::special_length_at(Bytecodes::Code code, address bcp, address end) {
|
||||
diff --git a/src/hotspot/share/interpreter/interpreterRuntime.cpp b/src/hotspot/share/interpreter/interpreterRuntime.cpp
|
||||
index ed3cc3eb6a2..504e59caf51 100644
|
||||
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp
|
||||
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp
|
||||
@@ -814,7 +814,7 @@ JRT_END
|
||||
// Invokes
|
||||
|
||||
JRT_ENTRY(Bytecodes::Code, InterpreterRuntime::get_original_bytecode_at(JavaThread* thread, Method* method, address bcp))
|
||||
- return method->orig_bytecode_at(method->bci_from(bcp));
|
||||
+ return method->orig_bytecode_at(method->bci_from(bcp), false);
|
||||
JRT_END
|
||||
|
||||
JRT_ENTRY(void, InterpreterRuntime::set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code))
|
||||
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
|
||||
index 516f2bb8f2f..1c88511a5fc 100644
|
||||
--- a/src/hotspot/share/oops/method.cpp
|
||||
+++ b/src/hotspot/share/oops/method.cpp
|
||||
@@ -1853,14 +1853,14 @@ bool CompressedLineNumberReadStream::read_pair() {
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
|
||||
-Bytecodes::Code Method::orig_bytecode_at(int bci) const {
|
||||
+Bytecodes::Code Method::orig_bytecode_at(int bci, bool no_fatal) const {
|
||||
BreakpointInfo* bp = method_holder()->breakpoints();
|
||||
for (; bp != NULL; bp = bp->next()) {
|
||||
if (bp->match(this, bci)) {
|
||||
return bp->orig_bytecode();
|
||||
}
|
||||
}
|
||||
- {
|
||||
+ if (!no_fatal) {
|
||||
ResourceMark rm;
|
||||
fatal("no original bytecode found in %s at bci %d", name_and_sig_as_C_string(), bci);
|
||||
}
|
||||
@@ -2006,7 +2006,7 @@ BreakpointInfo::BreakpointInfo(Method* m, int bci) {
|
||||
_signature_index = m->signature_index();
|
||||
_orig_bytecode = (Bytecodes::Code) *m->bcp_from(_bci);
|
||||
if (_orig_bytecode == Bytecodes::_breakpoint)
|
||||
- _orig_bytecode = m->orig_bytecode_at(_bci);
|
||||
+ _orig_bytecode = m->orig_bytecode_at(_bci, false);
|
||||
_next = NULL;
|
||||
}
|
||||
|
||||
@@ -2015,7 +2015,7 @@ void BreakpointInfo::set(Method* method) {
|
||||
{
|
||||
Bytecodes::Code code = (Bytecodes::Code) *method->bcp_from(_bci);
|
||||
if (code == Bytecodes::_breakpoint)
|
||||
- code = method->orig_bytecode_at(_bci);
|
||||
+ code = method->orig_bytecode_at(_bci, false);
|
||||
assert(orig_bytecode() == code, "original bytecode must be the same");
|
||||
}
|
||||
#endif
|
||||
diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp
|
||||
index 83ed2d9c3c1..4d4cc6dc012 100644
|
||||
--- a/src/hotspot/share/oops/method.hpp
|
||||
+++ b/src/hotspot/share/oops/method.hpp
|
||||
@@ -230,7 +230,7 @@ class Method : public Metadata {
|
||||
|
||||
// JVMTI breakpoints
|
||||
#if !INCLUDE_JVMTI
|
||||
- Bytecodes::Code orig_bytecode_at(int bci) const {
|
||||
+ Bytecodes::Code orig_bytecode_at(int bci, bool no_fatal) const {
|
||||
ShouldNotReachHere();
|
||||
return Bytecodes::_shouldnotreachhere;
|
||||
}
|
||||
@@ -239,7 +239,7 @@ class Method : public Metadata {
|
||||
};
|
||||
u2 number_of_breakpoints() const {return 0;}
|
||||
#else // !INCLUDE_JVMTI
|
||||
- Bytecodes::Code orig_bytecode_at(int bci) const;
|
||||
+ Bytecodes::Code orig_bytecode_at(int bci, bool no_fatal) const;
|
||||
void set_orig_bytecode_at(int bci, Bytecodes::Code code);
|
||||
void set_breakpoint(int bci);
|
||||
void clear_breakpoint(int bci);
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index 8b765623dcd..a859b8e1162 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -1362,14 +1362,16 @@ void VM_EnhancedRedefineClasses::unpatch_bytecode(Method* method) {
|
||||
|
||||
if (code == Bytecodes::_breakpoint) {
|
||||
int bci = method->bci_from(bcp);
|
||||
- code = method->orig_bytecode_at(bci);
|
||||
- java_code = Bytecodes::java_code(code);
|
||||
- if (code != java_code &&
|
||||
- (java_code == Bytecodes::_getfield ||
|
||||
- java_code == Bytecodes::_putfield ||
|
||||
- java_code == Bytecodes::_aload_0)) {
|
||||
- // Let breakpoint table handling unpatch bytecode
|
||||
- method->set_orig_bytecode_at(bci, java_code);
|
||||
+ code = method->orig_bytecode_at(bci, true);
|
||||
+ if (code != Bytecodes::_shouldnotreachhere) {
|
||||
+ java_code = Bytecodes::java_code(code);
|
||||
+ if (code != java_code &&
|
||||
+ (java_code == Bytecodes::_getfield ||
|
||||
+ java_code == Bytecodes::_putfield ||
|
||||
+ java_code == Bytecodes::_aload_0)) {
|
||||
+ // Let breakpoint table handling unpatch bytecode
|
||||
+ method->set_orig_bytecode_at(bci, java_code);
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
java_code = Bytecodes::java_code(code);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
From 19d2274a5dff6e6b31474252b45e5e7484f0180b Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 24 May 2020 12:07:42 +0200
|
||||
Subject: [PATCH 07/34] Replace deleted method with
|
||||
Universe::throw_no_such_method_error
|
||||
|
||||
---
|
||||
.../share/prims/resolvedMethodTable.cpp | 28 +++++++++----------
|
||||
1 file changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
index 81b3aa96564..caf03ffe56d 100644
|
||||
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
@@ -404,25 +404,25 @@ void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed)
|
||||
|
||||
if (old_method->is_old()) {
|
||||
|
||||
+ InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
|
||||
+ Method* newer_method;
|
||||
+
|
||||
// Method* new_method;
|
||||
if (old_method->is_deleted()) {
|
||||
- // FIXME:(DCEVM) - check if exception can be thrown
|
||||
- // new_method = Universe::throw_no_such_method_error();
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
|
||||
- Method* newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
|
||||
+ newer_method = Universe::throw_no_such_method_error();
|
||||
+ } else {
|
||||
+ newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
|
||||
|
||||
- log_info(redefine, class, load, exceptions)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
|
||||
+ log_info(redefine, class, load, exceptions)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
|
||||
|
||||
- assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
|
||||
- assert(newer_method != NULL, "method_with_idnum() should not be NULL");
|
||||
- assert(old_method != newer_method, "sanity check");
|
||||
+ assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
|
||||
+ assert(newer_method != NULL, "method_with_idnum() should not be NULL");
|
||||
+ assert(old_method != newer_method, "sanity check");
|
||||
|
||||
- if (_the_table->lookup(newer_method) != NULL) {
|
||||
- // old method was already adjusted if new method exists in _the_table
|
||||
- continue;
|
||||
+ if (_the_table->lookup(newer_method) != NULL) {
|
||||
+ // old method was already adjusted if new method exists in _the_table
|
||||
+ continue;
|
||||
+ }
|
||||
}
|
||||
|
||||
java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, newer_method);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
1310
jb/project/tools/patches/dcevm/0008-Support-for-G1-gc.patch
Normal file
1310
jb/project/tools/patches/dcevm/0008-Support-for-G1-gc.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
From ca47ab5a0a6ce8e2644736f323a335a957311af9 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sat, 13 Jun 2020 18:50:59 +0200
|
||||
Subject: [PATCH 09/34] Change log level in advanced redefinition
|
||||
|
||||
- Change log level for "Comparing different class ver.." to debug
|
||||
- Fix adjust_method_entries_dcevm logging levels and severity
|
||||
---
|
||||
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 2 +-
|
||||
src/hotspot/share/prims/resolvedMethodTable.cpp | 4 ++--
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index 6c9eb40ecf5..b09ba554e07 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -916,7 +916,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
// Calculated the difference between new and old class (field change, method change, supertype change, ...).
|
||||
int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_class) {
|
||||
int result = Klass::NoRedefinition;
|
||||
- log_info(redefine, class, load)("Comparing different class versions of class %s",new_class->name()->as_C_string());
|
||||
+ log_debug(redefine, class, load)("Comparing different class versions of class %s",new_class->name()->as_C_string());
|
||||
|
||||
assert(new_class->old_version() != NULL, "must have old version");
|
||||
InstanceKlass* the_class = InstanceKlass::cast(new_class->old_version());
|
||||
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
index caf03ffe56d..eb9fcda44f3 100644
|
||||
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
@@ -413,7 +413,7 @@ void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed)
|
||||
} else {
|
||||
newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
|
||||
|
||||
- log_info(redefine, class, load, exceptions)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
|
||||
+ log_debug(redefine, class, update)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
|
||||
|
||||
assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
|
||||
assert(newer_method != NULL, "method_with_idnum() should not be NULL");
|
||||
@@ -433,7 +433,7 @@ void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed)
|
||||
|
||||
ResourceMark rm;
|
||||
if (!(*trace_name_printed)) {
|
||||
- log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
|
||||
+ log_debug(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
|
||||
*trace_name_printed = true;
|
||||
}
|
||||
log_debug(redefine, class, update, constantpool)
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
From 7e236beee0375656d1955fc1168143c1639fb7f1 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Tue, 6 Oct 2020 22:15:31 +0200
|
||||
Subject: [PATCH 10/34] AllowEnhancedClassRedefinition is false (disabled) by
|
||||
default
|
||||
|
||||
---
|
||||
src/hotspot/share/runtime/globals.hpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
|
||||
index 5b367704800..2710c6ea0e5 100644
|
||||
--- a/src/hotspot/share/runtime/globals.hpp
|
||||
+++ b/src/hotspot/share/runtime/globals.hpp
|
||||
@@ -2466,7 +2466,7 @@ const size_t minimumSymbolTableSize = 1024;
|
||||
diagnostic(bool, DeoptimizeNMethodBarriersALot, false, \
|
||||
"Make nmethod barriers deoptimise a lot.") \
|
||||
\
|
||||
- product(bool, AllowEnhancedClassRedefinition, true, \
|
||||
+ product(bool, AllowEnhancedClassRedefinition, false, \
|
||||
"Allow enhanced class redefinition beyond swapping method " \
|
||||
"bodies") \
|
||||
\
|
||||
--
|
||||
2.23.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
From d56e73885111b386771f564ec6beb305338993df Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Mon, 19 Oct 2020 20:00:04 +0200
|
||||
Subject: [PATCH 12/34] Set HOTSPOT_VM_DISTRO=Dynamic Code Evolution
|
||||
|
||||
---
|
||||
make/autoconf/version-numbers | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/make/autoconf/version-numbers b/make/autoconf/version-numbers
|
||||
index aabdc5bed20..df8025a2e84 100644
|
||||
--- a/make/autoconf/version-numbers
|
||||
+++ b/make/autoconf/version-numbers
|
||||
@@ -45,7 +45,7 @@ PRODUCT_NAME=OpenJDK
|
||||
PRODUCT_SUFFIX="Runtime Environment"
|
||||
JDK_RC_PLATFORM_NAME=Platform
|
||||
COMPANY_NAME=N/A
|
||||
-HOTSPOT_VM_DISTRO="OpenJDK"
|
||||
+HOTSPOT_VM_DISTRO="Dynamic Code Evolution"
|
||||
VENDOR_URL=https://openjdk.java.net/
|
||||
VENDOR_URL_BUG=https://bugreport.java.com/bugreport/
|
||||
VENDOR_URL_VM_BUG=https://bugreport.java.com/bugreport/crash.jsp
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
From 7ebad43ed45805b0a3736c510f708ff17697ba7e Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 11 Oct 2020 10:43:28 +0200
|
||||
Subject: [PATCH 13/34] Fix G1 nmethod registration
|
||||
|
||||
---
|
||||
.../prims/jvmtiEnhancedRedefineClasses.cpp | 19 ++++++++++++++++---
|
||||
.../prims/jvmtiEnhancedRedefineClasses.hpp | 3 ++-
|
||||
2 files changed, 18 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index b09ba554e07..718426f2819 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -216,7 +216,14 @@ void VM_EnhancedRedefineClasses::mark_as_scavengable(nmethod* nm) {
|
||||
}
|
||||
}
|
||||
|
||||
-void VM_EnhancedRedefineClasses::mark_as_scavengable_g1(nmethod* nm) {
|
||||
+void VM_EnhancedRedefineClasses::unregister_nmethod_g1(nmethod* nm) {
|
||||
+ // It should work not only for G1 but also for another GCs, but this way is safer now
|
||||
+ if (!nm->is_zombie() && !nm->is_unloaded()) {
|
||||
+ Universe::heap()->unregister_nmethod(nm);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void VM_EnhancedRedefineClasses::register_nmethod_g1(nmethod* nm) {
|
||||
// It should work not only for G1 but also for another GCs, but this way is safer now
|
||||
if (!nm->is_zombie() && !nm->is_unloaded()) {
|
||||
Universe::heap()->register_nmethod(nm);
|
||||
@@ -521,8 +528,9 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
// For now, mark all nmethod's as scavengable that are not scavengable already
|
||||
if (ScavengeRootsInCode) {
|
||||
if (UseG1GC) {
|
||||
- // this should work also for other GCs
|
||||
- CodeCache::nmethods_do(mark_as_scavengable_g1);
|
||||
+ // G1 holds references to nmethods in regions based on oops values. Since oops in nmethod can be changed in ChangePointers* closures
|
||||
+ // we unregister nmethods from G1 heap, then closures are processed (oops are changed) and finally we register nmethod to G1 again
|
||||
+ CodeCache::nmethods_do(unregister_nmethod_g1);
|
||||
} else {
|
||||
CodeCache::nmethods_do(mark_as_scavengable);
|
||||
}
|
||||
@@ -545,6 +553,11 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
|
||||
Universe::root_oops_do(&oopClosureNoBarrier);
|
||||
|
||||
+ if (UseG1GC) {
|
||||
+ // this should work also for other GCs
|
||||
+ CodeCache::nmethods_do(register_nmethod_g1);
|
||||
+ }
|
||||
+
|
||||
}
|
||||
log_trace(redefine, class, obsolete, metadata)("After updating instances");
|
||||
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
index 9755944d70b..4c0412d343d 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
@@ -116,7 +116,8 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
|
||||
void rollback();
|
||||
static void mark_as_scavengable(nmethod* nm);
|
||||
- static void mark_as_scavengable_g1(nmethod* nm);
|
||||
+ static void unregister_nmethod_g1(nmethod* nm);
|
||||
+ static void register_nmethod_g1(nmethod* nm);
|
||||
static void unpatch_bytecode(Method* method);
|
||||
static void fix_invoke_method(Method* method);
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
From 5c7e5f245f79d7e8575461dab0c356ed74c8e9a3 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Thu, 22 Oct 2020 20:15:20 +0200
|
||||
Subject: [PATCH 14/34] Initialize method's _new_version/_old_version to NULL
|
||||
|
||||
---
|
||||
src/hotspot/share/oops/method.cpp | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
|
||||
index 1c88511a5fc..ce940cf10a9 100644
|
||||
--- a/src/hotspot/share/oops/method.cpp
|
||||
+++ b/src/hotspot/share/oops/method.cpp
|
||||
@@ -91,7 +91,8 @@ Method* Method::allocate(ClassLoaderData* loader_data,
|
||||
return new (loader_data, size, MetaspaceObj::MethodType, THREAD) Method(cm, access_flags);
|
||||
}
|
||||
|
||||
-Method::Method(ConstMethod* xconst, AccessFlags access_flags) {
|
||||
+Method::Method(ConstMethod* xconst, AccessFlags access_flags) : _new_version(NULL),
|
||||
+ _old_version(NULL) {
|
||||
NoSafepointVerifier no_safepoint;
|
||||
set_constMethod(xconst);
|
||||
set_access_flags(access_flags);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
From 6ffac6e5064ec6633fdbeb8520333dca00bc6a62 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Fri, 23 Oct 2020 10:20:26 +0200
|
||||
Subject: [PATCH 15/34] Clear dcevm code separation
|
||||
|
||||
---
|
||||
src/hotspot/share/classfile/systemDictionary.cpp | 4 ++--
|
||||
src/hotspot/share/gc/serial/genMarkSweep.cpp | 8 +++++---
|
||||
src/hotspot/share/interpreter/linkResolver.cpp | 16 +++++++++++-----
|
||||
.../instrumentation/jfrEventClassTransformer.cpp | 2 +-
|
||||
src/hotspot/share/oops/instanceKlass.cpp | 10 ++++++----
|
||||
src/hotspot/share/oops/method.cpp | 2 +-
|
||||
.../share/prims/jvmtiGetLoadedClasses.cpp | 2 +-
|
||||
src/hotspot/share/runtime/reflection.cpp | 2 +-
|
||||
8 files changed, 28 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
|
||||
index 8f2b46add4d..9ac6ec96cb5 100644
|
||||
--- a/src/hotspot/share/classfile/systemDictionary.cpp
|
||||
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
|
||||
@@ -1241,7 +1241,7 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name,
|
||||
MutexLocker mu(THREAD, SystemDictionary_lock);
|
||||
|
||||
Klass* check = find_class(h_name, k->class_loader_data());
|
||||
- assert((check == k && !k->is_redefining()) || (k->is_redefining() && check == k->old_version()), "should be present in the dictionary");
|
||||
+ assert(check == k && !k->is_redefining() || k->is_redefining() && check == k->old_version(), "should be present in the dictionary");
|
||||
} );
|
||||
|
||||
return k;
|
||||
@@ -2290,7 +2290,7 @@ void SystemDictionary::check_constraints(unsigned int d_hash,
|
||||
// also hold array classes.
|
||||
|
||||
assert(check->is_instance_klass(), "noninstance in systemdictionary");
|
||||
- if ((defining == true) || ((k != check) && k->old_version() != check)) {
|
||||
+ if ((defining == true) || (k != check && (!AllowEnhancedClassRedefinition || k->old_version() != check))) {
|
||||
throwException = true;
|
||||
ss.print("loader %s", loader_data->loader_name_and_id());
|
||||
ss.print(" attempted duplicate %s definition for %s. (%s)",
|
||||
diff --git a/src/hotspot/share/gc/serial/genMarkSweep.cpp b/src/hotspot/share/gc/serial/genMarkSweep.cpp
|
||||
index 1d13c647452..548df01e557 100644
|
||||
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp
|
||||
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp
|
||||
@@ -334,7 +334,9 @@ void GenMarkSweep::mark_sweep_phase4() {
|
||||
|
||||
GenCompactClosure blk;
|
||||
gch->generation_iterate(&blk, true);
|
||||
- DcevmSharedGC::copy_rescued_objects_back(MarkSweep::_rescued_oops, true);
|
||||
- DcevmSharedGC::clear_rescued_objects_resource(MarkSweep::_rescued_oops);
|
||||
- MarkSweep::_rescued_oops = NULL;
|
||||
+ if (AllowEnhancedClassRedefinition) {
|
||||
+ DcevmSharedGC::copy_rescued_objects_back(MarkSweep::_rescued_oops, true);
|
||||
+ DcevmSharedGC::clear_rescued_objects_resource(MarkSweep::_rescued_oops);
|
||||
+ MarkSweep::_rescued_oops = NULL;
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp
|
||||
index b6e9e0a308d..b2f24ddbeda 100644
|
||||
--- a/src/hotspot/share/interpreter/linkResolver.cpp
|
||||
+++ b/src/hotspot/share/interpreter/linkResolver.cpp
|
||||
@@ -282,9 +282,14 @@ void LinkResolver::check_klass_accessibility(Klass* ref_klass, Klass* sel_klass,
|
||||
if (!base_klass->is_instance_klass()) {
|
||||
return; // no relevant check to do
|
||||
}
|
||||
-
|
||||
- Reflection::VerifyClassAccessResults vca_result =
|
||||
- Reflection::verify_class_access(ref_klass->newest_version(), InstanceKlass::cast(base_klass->newest_version()), true);
|
||||
+ Klass* refKlassNewest = ref_klass;
|
||||
+ Klass* baseKlassNewest = base_klass;
|
||||
+ if (AllowEnhancedClassRedefinition) {
|
||||
+ refKlassNewest = ref_klass->newest_version();
|
||||
+ baseKlassNewest = base_klass->newest_version();
|
||||
+ }
|
||||
+ Reflection::VerifyClassAccessResults vca_result =
|
||||
+ Reflection::verify_class_access(refKlassNewest, InstanceKlass::cast(baseKlassNewest), true);
|
||||
if (vca_result != Reflection::ACCESS_OK) {
|
||||
ResourceMark rm(THREAD);
|
||||
char* msg = Reflection::verify_class_access_msg(ref_klass,
|
||||
@@ -566,7 +571,8 @@ void LinkResolver::check_method_accessability(Klass* ref_klass,
|
||||
// We'll check for the method name first, as that's most likely
|
||||
// to be false (so we'll short-circuit out of these tests).
|
||||
if (sel_method->name() == vmSymbols::clone_name() &&
|
||||
- sel_klass->newest_version() == SystemDictionary::Object_klass()->newest_version() &&
|
||||
+ ( !AllowEnhancedClassRedefinition && sel_klass == SystemDictionary::Object_klass() ||
|
||||
+ AllowEnhancedClassRedefinition && sel_klass->newest_version() == SystemDictionary::Object_klass()->newest_version()) &&
|
||||
resolved_klass->is_array_klass()) {
|
||||
// We need to change "protected" to "public".
|
||||
assert(flags.is_protected(), "clone not protected?");
|
||||
@@ -1011,7 +1017,7 @@ void LinkResolver::resolve_field(fieldDescriptor& fd,
|
||||
// or by the <init> method (in case of an instance field).
|
||||
if (is_put && fd.access_flags().is_final()) {
|
||||
|
||||
- if (sel_klass != current_klass && sel_klass != current_klass->active_version()) {
|
||||
+ if (sel_klass != current_klass && (!AllowEnhancedClassRedefinition || sel_klass != current_klass->active_version())) {
|
||||
ResourceMark rm(THREAD);
|
||||
stringStream ss;
|
||||
ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
|
||||
diff --git a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
|
||||
index 96fc139bea3..f7284197c5a 100644
|
||||
--- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
|
||||
+++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
|
||||
@@ -1471,7 +1471,7 @@ static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStre
|
||||
cld,
|
||||
&cl_info,
|
||||
ClassFileParser::INTERNAL, // internal visibility
|
||||
- false,
|
||||
+ false,
|
||||
THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
log_pending_exception(PENDING_EXCEPTION);
|
||||
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
|
||||
index 3be3a09ef8f..f8e60941046 100644
|
||||
--- a/src/hotspot/share/oops/instanceKlass.cpp
|
||||
+++ b/src/hotspot/share/oops/instanceKlass.cpp
|
||||
@@ -199,7 +199,9 @@ bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const {
|
||||
// able to perform that loading but we can't exclude the compiler threads from
|
||||
// executing this logic. But it should actually be impossible to trigger loading here.
|
||||
Klass* k2 = _constants->klass_at(cp_index, THREAD);
|
||||
- k2 = k2->newest_version();
|
||||
+ if (AllowEnhancedClassRedefinition) {
|
||||
+ k2 = k2->newest_version();
|
||||
+ }
|
||||
assert(!HAS_PENDING_EXCEPTION || PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass()),
|
||||
"Exceptions should not be possible here");
|
||||
if (k2 == k) {
|
||||
@@ -1003,7 +1005,7 @@ bool InstanceKlass::link_class_impl(TRAPS) {
|
||||
#endif
|
||||
set_init_state(linked);
|
||||
// (DCEVM) Must check for old version in order to prevent infinite loops.
|
||||
- if (JvmtiExport::should_post_class_prepare() && old_version() == NULL /* JVMTI deadlock otherwise */) {
|
||||
+ if (JvmtiExport::should_post_class_prepare() && (!AllowEnhancedClassRedefinition || old_version() == NULL) /* JVMTI deadlock otherwise */) {
|
||||
Thread *thread = THREAD;
|
||||
assert(thread->is_Java_thread(), "thread->is_Java_thread()");
|
||||
JvmtiExport::post_class_prepare((JavaThread *) thread, this);
|
||||
@@ -1084,7 +1086,7 @@ void InstanceKlass::initialize_impl(TRAPS) {
|
||||
// we might end up throwing IE from link/symbol resolution sites
|
||||
// that aren't expected to throw. This would wreak havoc. See 6320309.
|
||||
while ((is_being_initialized() && !is_reentrant_initialization(jt))
|
||||
- || (old_version() != NULL && InstanceKlass::cast(old_version())->is_being_initialized())) {
|
||||
+ || (AllowEnhancedClassRedefinition && old_version() != NULL && InstanceKlass::cast(old_version())->is_being_initialized())) {
|
||||
wait = true;
|
||||
jt->set_class_to_be_initialized(this);
|
||||
ol.wait_uninterruptibly(jt);
|
||||
@@ -3782,7 +3784,7 @@ void InstanceKlass::verify_on(outputStream* st) {
|
||||
|
||||
guarantee(sib->is_klass(), "should be klass");
|
||||
// TODO: (DCEVM) explain
|
||||
- guarantee(sib->super() == super || super->newest_version() == SystemDictionary::Object_klass(), "siblings should have same superklass");
|
||||
+ guarantee(sib->super() == super || AllowEnhancedClassRedefinition && super->newest_version() == SystemDictionary::Object_klass(), "siblings should have same superklass");
|
||||
}
|
||||
|
||||
// Verify local interfaces
|
||||
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
|
||||
index ce940cf10a9..2d8e5b0256b 100644
|
||||
--- a/src/hotspot/share/oops/method.cpp
|
||||
+++ b/src/hotspot/share/oops/method.cpp
|
||||
@@ -2208,7 +2208,7 @@ void Method::ensure_jmethod_ids(ClassLoaderData* loader_data, int capacity) {
|
||||
// Add a method id to the jmethod_ids
|
||||
jmethodID Method::make_jmethod_id(ClassLoaderData* loader_data, Method* m) {
|
||||
// FIXME: (DCEVM) ???
|
||||
- if (m != m->newest_version()) {
|
||||
+ if (AllowEnhancedClassRedefinition && m != m->newest_version()) {
|
||||
m = m->newest_version();
|
||||
}
|
||||
ClassLoaderData* cld = loader_data;
|
||||
diff --git a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
|
||||
index 1c7677f270f..6c12ee64a6e 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
// the new version (SystemDictionary stores only new versions). But the LoadedClassesClosure's functionality was
|
||||
// changed in java8 where jvmtiLoadedClasses collects all classes from all classloaders, therefore we
|
||||
// must use new versions only.
|
||||
- if (k->new_version()==NULL) {
|
||||
+ if (AllowEnhancedClassRedefinition && k->new_version()==NULL) {
|
||||
_classStack.push((jclass) _env->jni_reference(Handle(_cur_thread, k->java_mirror())));
|
||||
if (_dictionary_walk) {
|
||||
// Collect array classes this way when walking the dictionary (because array classes are
|
||||
diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp
|
||||
index 0e7722dba7d..d67457f02ac 100644
|
||||
--- a/src/hotspot/share/runtime/reflection.cpp
|
||||
+++ b/src/hotspot/share/runtime/reflection.cpp
|
||||
@@ -628,7 +628,7 @@ bool Reflection::verify_member_access(const Klass* current_class,
|
||||
TRAPS) {
|
||||
|
||||
// (DCEVM) Decide accessibility based on active version
|
||||
- if (current_class != NULL) {
|
||||
+ if (AllowEnhancedClassRedefinition && current_class != NULL) {
|
||||
current_class = current_class->active_version();
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
From dc675de6ac42819b8536827ea450fcad13a97448 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Wed, 11 Nov 2020 18:45:15 +0100
|
||||
Subject: [PATCH 16/34] Fix LoadedClassesClosure - fixes problems with remote
|
||||
debugging
|
||||
|
||||
---
|
||||
src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
|
||||
index 6c12ee64a6e..2a469555dbd 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
// the new version (SystemDictionary stores only new versions). But the LoadedClassesClosure's functionality was
|
||||
// changed in java8 where jvmtiLoadedClasses collects all classes from all classloaders, therefore we
|
||||
// must use new versions only.
|
||||
- if (AllowEnhancedClassRedefinition && k->new_version()==NULL) {
|
||||
+ if (!AllowEnhancedClassRedefinition || k->new_version()==NULL) {
|
||||
_classStack.push((jclass) _env->jni_reference(Handle(_cur_thread, k->java_mirror())));
|
||||
if (_dictionary_walk) {
|
||||
// Collect array classes this way when walking the dictionary (because array classes are
|
||||
--
|
||||
2.23.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,183 @@
|
||||
From 1d682efa88c716e1849163d5abff3a3367581d16 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Mon, 16 Nov 2020 21:11:19 +0100
|
||||
Subject: [PATCH 18/34] pre dcevm15 - fix GC spaces originally in removed CMS
|
||||
patch
|
||||
|
||||
---
|
||||
src/hotspot/share/gc/shared/space.cpp | 16 ++++++++--------
|
||||
src/hotspot/share/gc/shared/space.hpp | 6 +++---
|
||||
src/hotspot/share/gc/shared/space.inline.hpp | 14 ++++++++------
|
||||
.../share/prims/jvmtiEnhancedRedefineClasses.cpp | 6 ++----
|
||||
4 files changed, 21 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp
|
||||
index 875a6dc854f..9772c32c42e 100644
|
||||
--- a/src/hotspot/share/gc/shared/space.cpp
|
||||
+++ b/src/hotspot/share/gc/shared/space.cpp
|
||||
@@ -375,11 +375,11 @@ HeapWord* CompactibleSpace::forward_compact_top(size_t size, CompactPoint* cp, H
|
||||
}
|
||||
|
||||
HeapWord* CompactibleSpace::forward(oop q, size_t size,
|
||||
- CompactPoint* cp, HeapWord* compact_top) {
|
||||
+ CompactPoint* cp, HeapWord* compact_top, bool force_forward) {
|
||||
compact_top = forward_compact_top(size, cp, compact_top);
|
||||
|
||||
// store the forwarding pointer into the mark word
|
||||
- if (cast_from_oop<HeapWord*>(q) != compact_top || (size_t)q->size() != size) {
|
||||
+ if (force_forward || cast_from_oop<HeapWord*>(q) != compact_top || (size_t)q->size() != size) {
|
||||
q->forward_to(oop(compact_top));
|
||||
assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
|
||||
} else {
|
||||
@@ -501,7 +501,7 @@ bool CompactibleSpace::must_rescue(oop old_obj, oop new_obj) {
|
||||
|
||||
} else {
|
||||
assert(space_index(old_obj) != space_index(new_obj), "old_obj and new_obj must be in different spaces");
|
||||
- if (tenured_gen->is_in_reserved(new_obj)) {
|
||||
+ if (new_in_tenured) {
|
||||
// Must never rescue when moving from the new into the old generation.
|
||||
assert(GenCollectedHeap::heap()->young_gen()->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration");
|
||||
assert(space_index(old_obj) > space_index(new_obj), "must be");
|
||||
@@ -824,14 +824,14 @@ void OffsetTableContigSpace::verify() const {
|
||||
// Compute the forward sizes and leave out objects whose position could
|
||||
// possibly overlap other objects.
|
||||
HeapWord* CompactibleSpace::forward_with_rescue(HeapWord* q, size_t size,
|
||||
- CompactPoint* cp, HeapWord* compact_top) {
|
||||
+ CompactPoint* cp, HeapWord* compact_top, bool force_forward) {
|
||||
size_t forward_size = size;
|
||||
|
||||
// (DCEVM) There is a new version of the class of q => different size
|
||||
if (oop(q)->klass()->new_version() != NULL) {
|
||||
|
||||
size_t new_size = oop(q)->size_given_klass(oop(q)->klass()->new_version());
|
||||
- assert(size != new_size, "instances without changed size have to be updated prior to GC run");
|
||||
+ // assert(size != new_size, "instances without changed size have to be updated prior to GC run");
|
||||
forward_size = new_size;
|
||||
}
|
||||
|
||||
@@ -845,7 +845,7 @@ HeapWord* CompactibleSpace::forward_with_rescue(HeapWord* q, size_t size,
|
||||
return compact_top;
|
||||
}
|
||||
|
||||
- return forward(oop(q), forward_size, cp, compact_top);
|
||||
+ return forward(oop(q), forward_size, cp, compact_top, force_forward);
|
||||
}
|
||||
|
||||
// Compute the forwarding addresses for the objects that need to be rescued.
|
||||
@@ -861,11 +861,11 @@ HeapWord* CompactibleSpace::forward_rescued(CompactPoint* cp, HeapWord* compact_
|
||||
// (DCEVM) There is a new version of the class of q => different size
|
||||
if (oop(q)->klass()->new_version() != NULL) {
|
||||
size_t new_size = oop(q)->size_given_klass(oop(q)->klass()->new_version());
|
||||
- assert(size != new_size, "instances without changed size have to be updated prior to GC run");
|
||||
+ // assert(size != new_size, "instances without changed size have to be updated prior to GC run");
|
||||
size = new_size;
|
||||
}
|
||||
|
||||
- compact_top = cp->space->forward(oop(q), size, cp, compact_top);
|
||||
+ compact_top = cp->space->forward(oop(q), size, cp, compact_top, true);
|
||||
assert(compact_top <= end(), "must not write over end of space!");
|
||||
}
|
||||
MarkSweep::_rescued_oops->clear();
|
||||
diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp
|
||||
index c9bfc365f0f..f7648995454 100644
|
||||
--- a/src/hotspot/share/gc/shared/space.hpp
|
||||
+++ b/src/hotspot/share/gc/shared/space.hpp
|
||||
@@ -405,7 +405,7 @@ public:
|
||||
virtual void prepare_for_compaction(CompactPoint* cp) = 0;
|
||||
// MarkSweep support phase3
|
||||
DEBUG_ONLY(int space_index(oop obj));
|
||||
- bool must_rescue(oop old_obj, oop new_obj);
|
||||
+ virtual bool must_rescue(oop old_obj, oop new_obj);
|
||||
HeapWord* rescue(HeapWord* old_obj);
|
||||
virtual void adjust_pointers();
|
||||
// MarkSweep support phase4
|
||||
@@ -436,11 +436,11 @@ public:
|
||||
// function of the then-current compaction space, and updates "cp->threshold
|
||||
// accordingly".
|
||||
virtual HeapWord* forward(oop q, size_t size, CompactPoint* cp,
|
||||
- HeapWord* compact_top);
|
||||
+ HeapWord* compact_top, bool force_forward);
|
||||
// (DCEVM) same as forwad, but can rescue objects. Invoked only during
|
||||
// redefinition runs
|
||||
HeapWord* forward_with_rescue(HeapWord* q, size_t size, CompactPoint* cp,
|
||||
- HeapWord* compact_top);
|
||||
+ HeapWord* compact_top, bool force_forward);
|
||||
|
||||
HeapWord* forward_rescued(CompactPoint* cp, HeapWord* compact_top);
|
||||
|
||||
diff --git a/src/hotspot/share/gc/shared/space.inline.hpp b/src/hotspot/share/gc/shared/space.inline.hpp
|
||||
index 5a93e93471b..fa645423685 100644
|
||||
--- a/src/hotspot/share/gc/shared/space.inline.hpp
|
||||
+++ b/src/hotspot/share/gc/shared/space.inline.hpp
|
||||
@@ -163,6 +163,8 @@ inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* c
|
||||
HeapWord* cur_obj = space->bottom();
|
||||
HeapWord* scan_limit = space->scan_limit();
|
||||
|
||||
+ bool force_forward = false;
|
||||
+
|
||||
while (cur_obj < scan_limit) {
|
||||
assert(!space->scanned_block_is_obj(cur_obj) ||
|
||||
oop(cur_obj)->mark_raw().is_marked() || oop(cur_obj)->mark_raw().is_unlocked() ||
|
||||
@@ -174,14 +176,15 @@ inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* c
|
||||
size_t size = space->scanned_block_size(cur_obj);
|
||||
|
||||
if (redefinition_run) {
|
||||
- compact_top = cp->space->forward_with_rescue(cur_obj, size, cp, compact_top);
|
||||
+ compact_top = cp->space->forward_with_rescue(cur_obj, size, cp, compact_top, force_forward);
|
||||
if (first_dead == NULL && oop(cur_obj)->is_gc_marked()) {
|
||||
/* Was moved (otherwise, forward would reset mark),
|
||||
set first_dead to here */
|
||||
first_dead = cur_obj;
|
||||
+ force_forward = true;
|
||||
}
|
||||
} else {
|
||||
- compact_top = cp->space->forward(oop(cur_obj), size, cp, compact_top);
|
||||
+ compact_top = cp->space->forward(oop(cur_obj), size, cp, compact_top, false);
|
||||
}
|
||||
|
||||
cur_obj += size;
|
||||
@@ -197,9 +200,9 @@ inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* c
|
||||
|
||||
// see if we might want to pretend this object is alive so that
|
||||
// we don't have to compact quite as often.
|
||||
- if (cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
|
||||
+ if (!redefinition_run && cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
|
||||
oop obj = oop(cur_obj);
|
||||
- compact_top = cp->space->forward(obj, obj->size(), cp, compact_top);
|
||||
+ compact_top = cp->space->forward(obj, obj->size(), cp, compact_top, force_forward);
|
||||
end_of_live = end;
|
||||
} else {
|
||||
// otherwise, it really is a free region.
|
||||
@@ -362,8 +365,7 @@ inline void CompactibleSpace::scan_and_compact(SpaceType* space, bool redefiniti
|
||||
Prefetch::write(compaction_top, copy_interval);
|
||||
|
||||
// copy object and reinit its mark
|
||||
- assert(cur_obj != compaction_top || oop(cur_obj)->klass()->new_version() != NULL,
|
||||
- "everything in this pass should be moving");
|
||||
+ assert(redefinition_run || cur_obj != compaction_top, "everything in this pass should be moving");
|
||||
if (redefinition_run && oop(cur_obj)->klass()->new_version() != NULL) {
|
||||
Klass* new_version = oop(cur_obj)->klass()->new_version();
|
||||
if (new_version->update_information() == NULL) {
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index 718426f2819..1da6661dd3e 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -431,13 +431,11 @@ public:
|
||||
Klass* new_klass = obj->klass()->new_version();
|
||||
|
||||
if (new_klass->update_information() != NULL) {
|
||||
- int size_diff = obj->size() - obj->size_given_klass(new_klass);
|
||||
-
|
||||
- // Either new size is bigger or gap is to small to be filled
|
||||
- if (size_diff < 0 || (size_diff > 0 && (size_t) size_diff < CollectedHeap::min_fill_size())) {
|
||||
+ if (obj->size() - obj->size_given_klass(new_klass) != 0) {
|
||||
// We need an instance update => set back to old klass
|
||||
_needs_instance_update = true;
|
||||
} else {
|
||||
+ // Either new size is bigger or gap is to small to be filled
|
||||
oop src = obj;
|
||||
if (new_klass->is_copying_backwards()) {
|
||||
copy_to_tmp(obj);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,942 @@
|
||||
From 297f564f6af79fb824f5b4e9119f1d3d0c827fb0 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Mon, 16 Nov 2020 20:20:12 +0100
|
||||
Subject: [PATCH 19/34] dcevm15 - fix java15 patch compilation issues
|
||||
|
||||
---
|
||||
.../share/classfile/classFileParser.hpp | 8 +-
|
||||
.../share/classfile/classLoaderData.cpp | 2 +-
|
||||
src/hotspot/share/classfile/dictionary.hpp | 10 +-
|
||||
src/hotspot/share/classfile/javaClasses.hpp | 2 +
|
||||
.../share/gc/g1/g1FullGCCompactTask.cpp | 4 +-
|
||||
.../share/gc/g1/g1FullGCCompactionPoint.cpp | 8 +-
|
||||
.../share/gc/g1/g1FullGCPrepareTask.cpp | 4 +-
|
||||
src/hotspot/share/gc/shared/dcevmSharedGC.cpp | 14 +-
|
||||
src/hotspot/share/gc/shared/dcevmSharedGC.hpp | 2 +-
|
||||
src/hotspot/share/gc/shared/gcConfig.cpp | 2 +-
|
||||
src/hotspot/share/gc/shared/space.cpp | 4 +-
|
||||
.../share/interpreter/linkResolver.cpp | 2 +-
|
||||
src/hotspot/share/oops/instanceKlass.cpp | 17 ++-
|
||||
src/hotspot/share/oops/instanceKlass.hpp | 1 +
|
||||
src/hotspot/share/oops/klass.cpp | 8 +-
|
||||
src/hotspot/share/prims/jvm.cpp | 2 +
|
||||
.../prims/jvmtiEnhancedRedefineClasses.cpp | 129 +++++++++---------
|
||||
.../prims/jvmtiEnhancedRedefineClasses.hpp | 14 +-
|
||||
src/hotspot/share/prims/jvmtiEnv.cpp | 11 +-
|
||||
.../share/prims/jvmtiRedefineClasses.cpp | 1 +
|
||||
src/hotspot/share/prims/methodHandles.hpp | 3 +
|
||||
src/hotspot/share/runtime/arguments.cpp | 22 +--
|
||||
src/hotspot/share/runtime/mutexLocker.cpp | 2 +-
|
||||
23 files changed, 159 insertions(+), 113 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/classfile/classFileParser.hpp b/src/hotspot/share/classfile/classFileParser.hpp
|
||||
index e5761e61767..0d266b9047e 100644
|
||||
--- a/src/hotspot/share/classfile/classFileParser.hpp
|
||||
+++ b/src/hotspot/share/classfile/classFileParser.hpp
|
||||
@@ -150,9 +150,6 @@ class ClassFileParser {
|
||||
const intArray* _method_ordering;
|
||||
GrowableArray<Method*>* _all_mirandas;
|
||||
|
||||
- // Enhanced class redefinition
|
||||
- const bool _pick_newest;
|
||||
-
|
||||
enum { fixed_buffer_size = 128 };
|
||||
u_char _linenumbertable_buffer[fixed_buffer_size];
|
||||
|
||||
@@ -206,6 +203,9 @@ class ClassFileParser {
|
||||
bool _has_vanilla_constructor;
|
||||
int _max_bootstrap_specifier_index; // detects BSS values
|
||||
|
||||
+ // (DCEVM) Enhanced class redefinition
|
||||
+ const bool _pick_newest;
|
||||
+
|
||||
void parse_stream(const ClassFileStream* const stream, TRAPS);
|
||||
|
||||
void mangle_hidden_class_name(InstanceKlass* const ik);
|
||||
@@ -582,7 +582,7 @@ class ClassFileParser {
|
||||
ClassLoaderData* loader_data() const { return _loader_data; }
|
||||
const Symbol* class_name() const { return _class_name; }
|
||||
const InstanceKlass* super_klass() const { return _super_klass; }
|
||||
- Array<Klass*>* local_interfaces() const { return _local_interfaces; }
|
||||
+ Array<InstanceKlass*>* local_interfaces() const { return _local_interfaces; }
|
||||
|
||||
ReferenceType reference_type() const { return _rt; }
|
||||
AccessFlags access_flags() const { return _access_flags; }
|
||||
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
|
||||
index 4d64c6b454a..aadcd50ef4a 100644
|
||||
--- a/src/hotspot/share/classfile/classLoaderData.cpp
|
||||
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
|
||||
@@ -597,7 +597,7 @@ void ClassLoaderData::exchange_holders(ClassLoaderData* cld) {
|
||||
oop holder_oop = _holder.peek();
|
||||
_holder.replace(cld->_holder.peek());
|
||||
cld->_holder.replace(holder_oop);
|
||||
- WeakHandle<vm_class_loader_data> exchange = _holder;
|
||||
+ WeakHandle<vm_weak_data> exchange = _holder;
|
||||
_holder = cld->_holder;
|
||||
cld->_holder = exchange;
|
||||
}
|
||||
diff --git a/src/hotspot/share/classfile/dictionary.hpp b/src/hotspot/share/classfile/dictionary.hpp
|
||||
index 114a983e783..a50f4ff84d2 100644
|
||||
--- a/src/hotspot/share/classfile/dictionary.hpp
|
||||
+++ b/src/hotspot/share/classfile/dictionary.hpp
|
||||
@@ -84,6 +84,11 @@ public:
|
||||
void print_on(outputStream* st) const;
|
||||
void verify();
|
||||
|
||||
+ // (DCEVM) Enhanced class redefinition
|
||||
+ bool update_klass(unsigned int hash, Symbol* name, ClassLoaderData* loader_data, InstanceKlass* k, InstanceKlass* old_klass);
|
||||
+
|
||||
+ void rollback_redefinition();
|
||||
+
|
||||
private:
|
||||
DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass);
|
||||
|
||||
@@ -106,11 +111,6 @@ public:
|
||||
|
||||
void free_entry(DictionaryEntry* entry);
|
||||
|
||||
- // Enhanced class redefinition
|
||||
- bool update_klass(unsigned int hash, Symbol* name, ClassLoaderData* loader_data, InstanceKlass* k, InstanceKlass* old_klass);
|
||||
-
|
||||
- void rollback_redefinition();
|
||||
-
|
||||
// (DCEVM) return old class if redefining in AllowEnhancedClassRedefinition, otherwise return "k"
|
||||
static InstanceKlass* old_if_redefined(InstanceKlass* k) {
|
||||
return (k != NULL && k->is_redefining()) ? ((InstanceKlass* )k->old_version()) : k;
|
||||
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
|
||||
index a68c5139151..9abf2e1d105 100644
|
||||
--- a/src/hotspot/share/classfile/javaClasses.hpp
|
||||
+++ b/src/hotspot/share/classfile/javaClasses.hpp
|
||||
@@ -255,7 +255,9 @@ class java_lang_Class : AllStatic {
|
||||
static void set_init_lock(oop java_class, oop init_lock);
|
||||
static void set_protection_domain(oop java_class, oop protection_domain);
|
||||
static void set_class_loader(oop java_class, oop class_loader);
|
||||
+ public: // DCEVM
|
||||
static void set_component_mirror(oop java_class, oop comp_mirror);
|
||||
+ private:
|
||||
static void initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain,
|
||||
Handle classData, TRAPS);
|
||||
static void initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain, TRAPS);
|
||||
diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp
|
||||
index f70f4606dc8..a22ed48560d 100644
|
||||
--- a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp
|
||||
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp
|
||||
@@ -157,14 +157,14 @@ void G1FullGCCompactTask::serial_compaction_dcevm() {
|
||||
|
||||
size_t G1FullGCCompactTask::G1CompactRegionClosureDcevm::apply(oop obj) {
|
||||
size_t size = obj->size();
|
||||
- HeapWord* destination = (HeapWord*)obj->forwardee();
|
||||
+ HeapWord* destination = cast_from_oop<HeapWord*>(obj->forwardee());
|
||||
if (destination == NULL) {
|
||||
// Object not moving
|
||||
return size;
|
||||
}
|
||||
|
||||
// copy object and reinit its mark
|
||||
- HeapWord* obj_addr = (HeapWord*) obj;
|
||||
+ HeapWord* obj_addr = cast_from_oop<HeapWord*>(obj);
|
||||
|
||||
if (!_rescue_oops_it->at_end() && **_rescue_oops_it == obj_addr) {
|
||||
++(*_rescue_oops_it);
|
||||
diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp
|
||||
index 1e49571c999..755935a2c91 100644
|
||||
--- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp
|
||||
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp
|
||||
@@ -174,7 +174,7 @@ void G1FullGCCompactionPoint::forward_dcevm(oop object, size_t size, bool force_
|
||||
assert(_current_region != NULL, "Must have been initialized");
|
||||
|
||||
// Store a forwarding pointer if the object should be moved.
|
||||
- if ((HeapWord*)object != _compaction_top || force_forward) {
|
||||
+ if (cast_from_oop<HeapWord*>(object) != _compaction_top || force_forward) {
|
||||
object->forward_to(oop(_compaction_top));
|
||||
} else {
|
||||
if (object->forwardee() != NULL) {
|
||||
@@ -188,11 +188,11 @@ void G1FullGCCompactionPoint::forward_dcevm(oop object, size_t size, bool force_
|
||||
} else {
|
||||
// Make sure object has the correct mark-word set or that it will be
|
||||
// fixed when restoring the preserved marks.
|
||||
- assert(object->mark_raw() == markOopDesc::prototype_for_object(object) || // Correct mark
|
||||
- object->mark_raw()->must_be_preserved(object) || // Will be restored by PreservedMarksSet
|
||||
+ assert(object->mark_raw() == markWord::prototype_for_klass(object->klass()) || // Correct mark
|
||||
+ object->mark_must_be_preserved() || // Will be restored by PreservedMarksSet
|
||||
(UseBiasedLocking && object->has_bias_pattern_raw()), // Will be restored by BiasedLocking
|
||||
"should have correct prototype obj: " PTR_FORMAT " mark: " PTR_FORMAT " prototype: " PTR_FORMAT,
|
||||
- p2i(object), p2i(object->mark_raw()), p2i(markOopDesc::prototype_for_object(object)));
|
||||
+ p2i(object), object->mark_raw().value(), markWord::prototype_for_klass(object->klass()).value());
|
||||
}
|
||||
assert(object->forwardee() == NULL, "should be forwarded to NULL");
|
||||
}
|
||||
diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
|
||||
index a45681b60cf..2f06b9617e4 100644
|
||||
--- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
|
||||
+++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
|
||||
@@ -269,7 +269,7 @@ size_t G1FullGCPrepareTask::G1PrepareCompactLiveClosureDcevm::apply(oop object)
|
||||
HeapWord* compact_top = _cp->forward_compact_top(forward_size);
|
||||
|
||||
if (compact_top == NULL || must_rescue(object, oop(compact_top))) {
|
||||
- _cp->rescued_oops()->append((HeapWord*)object);
|
||||
+ _cp->rescued_oops()->append(cast_from_oop<HeapWord*>(object));
|
||||
} else {
|
||||
_cp->forward_dcevm(object, forward_size, (size != forward_size));
|
||||
}
|
||||
@@ -295,7 +295,7 @@ bool G1FullGCPrepareTask::G1PrepareCompactLiveClosureDcevm::must_rescue(oop old_
|
||||
int new_size = old_obj->size_given_klass(oop(old_obj)->klass()->new_version());
|
||||
int original_size = old_obj->size();
|
||||
|
||||
- bool overlap = ((HeapWord*)old_obj + original_size < (HeapWord*)new_obj + new_size);
|
||||
+ bool overlap = (cast_from_oop<HeapWord*>(old_obj) + original_size < cast_from_oop<HeapWord*>(new_obj) + new_size);
|
||||
|
||||
return overlap;
|
||||
}
|
||||
diff --git a/src/hotspot/share/gc/shared/dcevmSharedGC.cpp b/src/hotspot/share/gc/shared/dcevmSharedGC.cpp
|
||||
index 803e645f843..3dee097f1d3 100644
|
||||
--- a/src/hotspot/share/gc/shared/dcevmSharedGC.cpp
|
||||
+++ b/src/hotspot/share/gc/shared/dcevmSharedGC.cpp
|
||||
@@ -58,10 +58,10 @@ void DcevmSharedGC::copy_rescued_objects_back(GrowableArray<HeapWord*>* rescued_
|
||||
DcevmSharedGC::update_fields(rescued_obj, new_obj);
|
||||
} else {
|
||||
rescued_obj->set_klass(new_klass);
|
||||
- Copy::aligned_disjoint_words((HeapWord*)rescued_obj, (HeapWord*)new_obj, size);
|
||||
+ Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(rescued_obj), cast_from_oop<HeapWord*>(new_obj), size);
|
||||
}
|
||||
} else {
|
||||
- Copy::aligned_disjoint_words((HeapWord*)rescued_obj, (HeapWord*)new_obj, size);
|
||||
+ Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(rescued_obj), cast_from_oop<HeapWord*>(new_obj), size);
|
||||
}
|
||||
|
||||
new_obj->init_mark_raw();
|
||||
@@ -111,11 +111,11 @@ void DcevmSharedGC::update_fields(oop q, oop new_location) {
|
||||
|
||||
// Save object somewhere, there is an overlap in fields
|
||||
if (new_klass_oop->is_copying_backwards()) {
|
||||
- if (((HeapWord *)q >= (HeapWord *)new_location && (HeapWord *)q < (HeapWord *)new_location + new_size) ||
|
||||
- ((HeapWord *)new_location >= (HeapWord *)q && (HeapWord *)new_location < (HeapWord *)q + size)) {
|
||||
+ if ((cast_from_oop<HeapWord*>(q) >= cast_from_oop<HeapWord*>(new_location) && cast_from_oop<HeapWord*>(q) < cast_from_oop<HeapWord*>(new_location) + new_size) ||
|
||||
+ (cast_from_oop<HeapWord*>(new_location) >= cast_from_oop<HeapWord*>(q) && cast_from_oop<HeapWord*>(new_location) < cast_from_oop<HeapWord*>(q) + size)) {
|
||||
tmp = NEW_RESOURCE_ARRAY(HeapWord, size);
|
||||
q = (oop) tmp;
|
||||
- Copy::aligned_disjoint_words((HeapWord*)tmp_obj, (HeapWord*)q, size);
|
||||
+ Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(tmp_obj), cast_from_oop<HeapWord*>(q), size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,13 +131,13 @@ void DcevmSharedGC::update_fields(oop q, oop new_location) {
|
||||
|
||||
void DcevmSharedGC::update_fields(oop new_location, oop tmp_obj, int *cur) {
|
||||
assert(cur != NULL, "just checking");
|
||||
- char* to = (char*)(HeapWord*)new_location;
|
||||
+ char* to = (char*)cast_from_oop<HeapWord*>(new_location);
|
||||
while (*cur != 0) {
|
||||
int size = *cur;
|
||||
if (size > 0) {
|
||||
cur++;
|
||||
int offset = *cur;
|
||||
- HeapWord* from = (HeapWord*)(((char *)(HeapWord*)tmp_obj) + offset);
|
||||
+ HeapWord* from = (HeapWord*)(((char *)cast_from_oop<HeapWord*>(tmp_obj)) + offset);
|
||||
if (size == HeapWordSize) {
|
||||
*((HeapWord*)to) = *from;
|
||||
} else if (size == HeapWordSize * 2) {
|
||||
diff --git a/src/hotspot/share/gc/shared/dcevmSharedGC.hpp b/src/hotspot/share/gc/shared/dcevmSharedGC.hpp
|
||||
index e2ef0171fb2..a4e27e00280 100644
|
||||
--- a/src/hotspot/share/gc/shared/dcevmSharedGC.hpp
|
||||
+++ b/src/hotspot/share/gc/shared/dcevmSharedGC.hpp
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "gc/shared/genOopClosures.hpp"
|
||||
#include "gc/shared/taskqueue.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
-#include "oops/markOop.hpp"
|
||||
+#include "oops/markWord.hpp"
|
||||
#include "oops/oop.hpp"
|
||||
#include "runtime/timer.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp
|
||||
index f01d64d1434..5c1a09390f1 100644
|
||||
--- a/src/hotspot/share/gc/shared/gcConfig.cpp
|
||||
+++ b/src/hotspot/share/gc/shared/gcConfig.cpp
|
||||
@@ -100,7 +100,7 @@ void GCConfig::fail_if_non_included_gc_is_selected() {
|
||||
void GCConfig::select_gc_ergonomically() {
|
||||
if (AllowEnhancedClassRedefinition && !UseG1GC) {
|
||||
// Enhanced class redefinition only supports serial GC at the moment
|
||||
- FLAG_SET_ERGO(bool, UseSerialGC, true);
|
||||
+ FLAG_SET_ERGO(UseSerialGC, true);
|
||||
} else if (os::is_server_class_machine()) {
|
||||
#if INCLUDE_G1GC
|
||||
FLAG_SET_ERGO_IF_DEFAULT(UseG1GC, true);
|
||||
diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp
|
||||
index 9772c32c42e..e8e3d7884c2 100644
|
||||
--- a/src/hotspot/share/gc/shared/space.cpp
|
||||
+++ b/src/hotspot/share/gc/shared/space.cpp
|
||||
@@ -440,7 +440,7 @@ int CompactibleSpace::space_index(oop obj) {
|
||||
index++;
|
||||
}
|
||||
|
||||
- tty->print_cr("could not compute space_index for %08xh", (HeapWord*)obj);
|
||||
+ tty->print_cr("could not compute space_index for %08xh", cast_from_oop<HeapWord*>(obj));
|
||||
index = 0;
|
||||
|
||||
Generation* gen = heap->old_gen();
|
||||
@@ -485,7 +485,7 @@ bool CompactibleSpace::must_rescue(oop old_obj, oop new_obj) {
|
||||
bool new_in_tenured = tenured_gen->is_in_reserved(new_obj);
|
||||
if (old_in_tenured == new_in_tenured) {
|
||||
// Rescue if object may overlap with a higher memory address.
|
||||
- bool overlap = ((HeapWord*)old_obj + original_size < (HeapWord*)new_obj + new_size);
|
||||
+ bool overlap = (cast_from_oop<HeapWord*>(old_obj) + original_size < cast_from_oop<HeapWord*>(new_obj) + new_size);
|
||||
if (old_in_tenured) {
|
||||
// Old and new address are in same space, so just compare the address.
|
||||
// Must rescue if object moves towards the top of the space.
|
||||
diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp
|
||||
index b2f24ddbeda..9daeeb70b34 100644
|
||||
--- a/src/hotspot/share/interpreter/linkResolver.cpp
|
||||
+++ b/src/hotspot/share/interpreter/linkResolver.cpp
|
||||
@@ -1031,7 +1031,7 @@ void LinkResolver::resolve_field(fieldDescriptor& fd,
|
||||
assert(m != NULL, "information about the current method must be available for 'put' bytecodes");
|
||||
bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic &&
|
||||
fd.is_static() &&
|
||||
- !(m()->is_static_initializer() || m()->name() == vmSymbols::ha_class_initializer_name()));
|
||||
+ !(m->is_static_initializer() || m->name() == vmSymbols::ha_class_initializer_name()));
|
||||
bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) &&
|
||||
!fd.is_static() &&
|
||||
!m->is_object_initializer());
|
||||
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
|
||||
index f8e60941046..5e40d78a87e 100644
|
||||
--- a/src/hotspot/share/oops/instanceKlass.cpp
|
||||
+++ b/src/hotspot/share/oops/instanceKlass.cpp
|
||||
@@ -1316,7 +1316,7 @@ void InstanceKlass::init_implementor() {
|
||||
// (DCEVM) - init_implementor() for dcevm
|
||||
void InstanceKlass::init_implementor_from_redefine() {
|
||||
assert(is_interface(), "not interface");
|
||||
- Klass** addr = adr_implementor();
|
||||
+ Klass* volatile* addr = adr_implementor();
|
||||
assert(addr != NULL, "null addr");
|
||||
if (addr != NULL) {
|
||||
*addr = NULL;
|
||||
@@ -1659,6 +1659,21 @@ void InstanceKlass::methods_do(void f(Method* method)) {
|
||||
}
|
||||
}
|
||||
|
||||
+void InstanceKlass::methods_do(void f(Method* method, TRAPS), TRAPS) {
|
||||
+ // Methods aren't stable until they are loaded. This can be read outside
|
||||
+ // a lock through the ClassLoaderData for profiling
|
||||
+ if (!is_loaded()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ int len = methods()->length();
|
||||
+ for (int index = 0; index < len; index++) {
|
||||
+ Method* m = methods()->at(index);
|
||||
+ assert(m->is_method(), "must be method");
|
||||
+ f(m, CHECK);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// (DCEVM) Update information contains mapping of fields from old class to the new class.
|
||||
// Info is stored on HEAP, you need to call clear_update_information to free the space.
|
||||
void InstanceKlass::store_update_information(GrowableArray<int> &values) {
|
||||
diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp
|
||||
index 6ead9426728..b56d42cb177 100644
|
||||
--- a/src/hotspot/share/oops/instanceKlass.hpp
|
||||
+++ b/src/hotspot/share/oops/instanceKlass.hpp
|
||||
@@ -1069,6 +1069,7 @@ public:
|
||||
void clear_update_information();
|
||||
|
||||
void methods_do(void f(Method* method));
|
||||
+ void methods_do(void f(Method* method, TRAPS), TRAPS);
|
||||
void array_klasses_do(void f(Klass* k));
|
||||
void array_klasses_do(void f(Klass* k, TRAPS), TRAPS);
|
||||
|
||||
diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp
|
||||
index 352d8f84631..88f5ec9ba4a 100644
|
||||
--- a/src/hotspot/share/oops/klass.cpp
|
||||
+++ b/src/hotspot/share/oops/klass.cpp
|
||||
@@ -200,13 +200,13 @@ void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word
|
||||
Klass::Klass(KlassID id) : _id(id),
|
||||
_java_mirror(NULL),
|
||||
_prototype_header(markWord::prototype()),
|
||||
- _shared_class_path_index(-1),
|
||||
- _new_version(NULL),
|
||||
_old_version(NULL),
|
||||
+ _new_version(NULL),
|
||||
+ _redefinition_flags(Klass::NoRedefinition),
|
||||
_is_redefining(false),
|
||||
+ _update_information(NULL),
|
||||
_is_copying_backwards(false),
|
||||
- _redefinition_flags(Klass::NoRedefinition),
|
||||
- _update_information(NULL) {
|
||||
+ _shared_class_path_index(-1) {
|
||||
CDS_ONLY(_shared_class_flags = 0;)
|
||||
CDS_JAVA_HEAP_ONLY(_archived_mirror = 0;)
|
||||
_primary_supers[0] = this;
|
||||
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
|
||||
index 333b65ccfc1..13bcac352fb 100644
|
||||
--- a/src/hotspot/share/prims/jvm.cpp
|
||||
+++ b/src/hotspot/share/prims/jvm.cpp
|
||||
@@ -1054,6 +1054,7 @@ static jclass jvm_lookup_define_class(JNIEnv *env, jclass lookup, const char *na
|
||||
class_loader,
|
||||
protection_domain,
|
||||
&st,
|
||||
+ NULL,
|
||||
CHECK_NULL);
|
||||
|
||||
if (log_is_enabled(Debug, class, resolve) && defined_k != NULL) {
|
||||
@@ -1074,6 +1075,7 @@ static jclass jvm_lookup_define_class(JNIEnv *env, jclass lookup, const char *na
|
||||
class_loader,
|
||||
&st,
|
||||
cl_info,
|
||||
+ NULL,
|
||||
CHECK_NULL);
|
||||
if (defined_k == NULL) {
|
||||
THROW_MSG_0(vmSymbols::java_lang_Error(), "Failure to define a hidden class");
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index 1da6661dd3e..619e3988e3a 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -24,11 +24,14 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "aot/aotLoader.hpp"
|
||||
+#include "classfile/classFileParser.hpp"
|
||||
#include "classfile/classFileStream.hpp"
|
||||
#include "classfile/metadataOnStackMark.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/verifier.hpp"
|
||||
#include "classfile/dictionary.hpp"
|
||||
+#include "classfile/classLoaderDataGraph.hpp"
|
||||
+#include "interpreter/linkResolver.hpp"
|
||||
#include "interpreter/oopMapCache.hpp"
|
||||
#include "interpreter/rewriter.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
@@ -37,17 +40,22 @@
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/iterator.inline.hpp"
|
||||
#include "oops/fieldStreams.hpp"
|
||||
+#include "oops/fieldStreams.inline.hpp"
|
||||
#include "oops/klassVtable.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/constantPool.inline.hpp"
|
||||
+#include "oops/metadata.hpp"
|
||||
+#include "oops/methodData.hpp"
|
||||
#include "prims/jvmtiImpl.hpp"
|
||||
#include "prims/jvmtiClassFileReconstituter.hpp"
|
||||
#include "prims/jvmtiEnhancedRedefineClasses.hpp"
|
||||
#include "prims/methodComparator.hpp"
|
||||
#include "prims/resolvedMethodTable.hpp"
|
||||
+#include "prims/methodHandles.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/jniHandles.inline.hpp"
|
||||
#include "runtime/relocator.hpp"
|
||||
+#include "runtime/fieldDescriptor.hpp"
|
||||
#include "runtime/fieldDescriptor.inline.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
#include "prims/jvmtiThreadState.inline.hpp"
|
||||
@@ -55,6 +63,8 @@
|
||||
#include "oops/constantPool.inline.hpp"
|
||||
#include "gc/g1/g1CollectedHeap.hpp"
|
||||
#include "gc/shared/dcevmSharedGC.hpp"
|
||||
+#include "gc/shared/scavengableNMethods.hpp"
|
||||
+#include "ci/ciObjectFactory.hpp"
|
||||
|
||||
Array<Method*>* VM_EnhancedRedefineClasses::_old_methods = NULL;
|
||||
Array<Method*>* VM_EnhancedRedefineClasses::_new_methods = NULL;
|
||||
@@ -66,6 +76,7 @@ int VM_EnhancedRedefineClasses::_matching_methods_length = 0;
|
||||
int VM_EnhancedRedefineClasses::_deleted_methods_length = 0;
|
||||
int VM_EnhancedRedefineClasses::_added_methods_length = 0;
|
||||
Klass* VM_EnhancedRedefineClasses::_the_class_oop = NULL;
|
||||
+u8 VM_EnhancedRedefineClasses::_id_counter = 0;
|
||||
|
||||
//
|
||||
// Create new instance of enhanced class redefiner.
|
||||
@@ -88,6 +99,7 @@ VM_EnhancedRedefineClasses::VM_EnhancedRedefineClasses(jint class_count, const j
|
||||
_class_load_kind = class_load_kind;
|
||||
_res = JVMTI_ERROR_NONE;
|
||||
_any_class_has_resolved_methods = false;
|
||||
+ _id = next_id();
|
||||
}
|
||||
|
||||
static inline InstanceKlass* get_ik(jclass def) {
|
||||
@@ -211,9 +223,7 @@ class FieldCopier : public FieldClosure {
|
||||
|
||||
// TODO: review...
|
||||
void VM_EnhancedRedefineClasses::mark_as_scavengable(nmethod* nm) {
|
||||
- if (!nm->on_scavenge_root_list()) {
|
||||
- CodeCache::add_scavenge_root_nmethod(nm);
|
||||
- }
|
||||
+ ScavengableNMethods::register_nmethod(nm);
|
||||
}
|
||||
|
||||
void VM_EnhancedRedefineClasses::unregister_nmethod_g1(nmethod* nm) {
|
||||
@@ -414,7 +424,7 @@ public:
|
||||
_tmp_obj_size = size;
|
||||
_tmp_obj = (oop)resource_allocate_bytes(size * HeapWordSize);
|
||||
}
|
||||
- Copy::aligned_disjoint_words((HeapWord*)o, (HeapWord*)_tmp_obj, size);
|
||||
+ Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(o), cast_from_oop<HeapWord*>(_tmp_obj), size);
|
||||
}
|
||||
|
||||
virtual void do_object(oop obj) {
|
||||
@@ -505,9 +515,6 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
ClearCpoolCacheAndUnpatch clear_cpool_cache(thread);
|
||||
ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
|
||||
|
||||
-
|
||||
- // SystemDictionary::methods_do(fix_invoke_method);
|
||||
-
|
||||
// JSR-292 support
|
||||
if (_any_class_has_resolved_methods) {
|
||||
bool trace_name_printed = false;
|
||||
@@ -564,8 +571,8 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
InstanceKlass* old = InstanceKlass::cast(cur->old_version());
|
||||
|
||||
// Swap marks to have same hashcodes
|
||||
- markOop cur_mark = cur->prototype_header();
|
||||
- markOop old_mark = old->prototype_header();
|
||||
+ markWord cur_mark = cur->prototype_header();
|
||||
+ markWord old_mark = old->prototype_header();
|
||||
cur->set_prototype_header(old_mark);
|
||||
old->set_prototype_header(cur_mark);
|
||||
|
||||
@@ -579,14 +586,14 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
// Revert pool holder for old version of klass (it was updated by one of ours closure!)
|
||||
old->constants()->set_pool_holder(old);
|
||||
|
||||
- Klass* array_klasses = old->array_klasses();
|
||||
+ ObjArrayKlass* array_klasses = old->array_klasses();
|
||||
if (array_klasses != NULL) {
|
||||
assert(cur->array_klasses() == NULL, "just checking");
|
||||
|
||||
// Transfer the array classes, otherwise we might get cast exceptions when casting array types.
|
||||
// Also, set array klasses element klass.
|
||||
cur->set_array_klasses(array_klasses);
|
||||
- ObjArrayKlass::cast(array_klasses)->set_element_klass(cur);
|
||||
+ array_klasses->set_element_klass(cur);
|
||||
java_lang_Class::release_set_array_klass(cur->java_mirror(), array_klasses);
|
||||
java_lang_Class::set_component_mirror(array_klasses->java_mirror(), cur->java_mirror());
|
||||
}
|
||||
@@ -641,11 +648,15 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
//ClassLoaderDataGraph::classes_do(&clean_weak_method_links);
|
||||
|
||||
// Disable any dependent concurrent compilations
|
||||
- SystemDictionary::notice_modification();
|
||||
+ // SystemDictionary::notice_modification();
|
||||
+
|
||||
+ JvmtiExport::increment_redefinition_count();
|
||||
|
||||
// Set flag indicating that some invariants are no longer true.
|
||||
// See jvmtiExport.hpp for detailed explanation.
|
||||
- JvmtiExport::set_has_redefined_a_class();
|
||||
+
|
||||
+ // dcevm15: handled by _redefinition_count
|
||||
+ // JvmtiExport::set_has_redefined_a_class();
|
||||
|
||||
#ifdef PRODUCT
|
||||
if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
|
||||
@@ -718,7 +729,7 @@ bool VM_EnhancedRedefineClasses::is_modifiable_class(oop klass_mirror) {
|
||||
}
|
||||
|
||||
// Cannot redefine or retransform an anonymous class.
|
||||
- if (InstanceKlass::cast(k)->is_anonymous()) {
|
||||
+ if (InstanceKlass::cast(k)->is_unsafe_anonymous()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -804,22 +815,30 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
|
||||
InstanceKlass* k;
|
||||
|
||||
- if (InstanceKlass::cast(the_class)->is_anonymous()) {
|
||||
- const InstanceKlass* host_class = the_class->host_klass();
|
||||
+ if (InstanceKlass::cast(the_class)->is_unsafe_anonymous()) {
|
||||
+ const InstanceKlass* host_class = the_class->unsafe_anonymous_host();
|
||||
|
||||
// Make sure it's the real host class, not another anonymous class.
|
||||
- while (host_class != NULL && host_class->is_anonymous()) {
|
||||
- host_class = host_class->host_klass();
|
||||
+ while (host_class != NULL && host_class->is_unsafe_anonymous()) {
|
||||
+ host_class = host_class->unsafe_anonymous_host();
|
||||
}
|
||||
|
||||
+ ClassLoadInfo cl_info(protection_domain,
|
||||
+ host_class,
|
||||
+ NULL, // dynamic_nest_host
|
||||
+ NULL, // cp_patches
|
||||
+ Handle(), // classData
|
||||
+ false, // is_hidden
|
||||
+ false, // is_strong_hidden
|
||||
+ true); // FIXME: check if correct. can_access_vm_annotations
|
||||
+
|
||||
k = SystemDictionary::parse_stream(the_class_sym,
|
||||
the_class_loader,
|
||||
- protection_domain,
|
||||
&st,
|
||||
- host_class,
|
||||
+ cl_info,
|
||||
the_class,
|
||||
- NULL,
|
||||
THREAD);
|
||||
+
|
||||
k->class_loader_data()->exchange_holders(the_class->class_loader_data());
|
||||
the_class->class_loader_data()->inc_keep_alive();
|
||||
} else {
|
||||
@@ -966,7 +985,7 @@ int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_
|
||||
// Check interfaces
|
||||
|
||||
// Interfaces removed?
|
||||
- Array<Klass*>* old_interfaces = the_class->transitive_interfaces();
|
||||
+ Array<InstanceKlass*>* old_interfaces = the_class->transitive_interfaces();
|
||||
for (i = 0; i < old_interfaces->length(); i++) {
|
||||
InstanceKlass* old_interface = InstanceKlass::cast(old_interfaces->at(i));
|
||||
if (!new_class->implements_interface_any_version(old_interface)) {
|
||||
@@ -976,7 +995,7 @@ int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_
|
||||
}
|
||||
|
||||
// Interfaces added?
|
||||
- Array<Klass*>* new_interfaces = new_class->transitive_interfaces();
|
||||
+ Array<InstanceKlass*>* new_interfaces = new_class->transitive_interfaces();
|
||||
for (i = 0; i<new_interfaces->length(); i++) {
|
||||
if (!the_class->implements_interface_any_version(new_interfaces->at(i))) {
|
||||
result = result | Klass::ModifyClass;
|
||||
@@ -1389,8 +1408,8 @@ void VM_EnhancedRedefineClasses::rollback() {
|
||||
// Rewrite faster byte-codes back to their slower equivalent. Undoes rewriting happening in templateTable_xxx.cpp
|
||||
// The reason is that once we zero cpool caches, we need to re-resolve all entries again. Faster bytecodes do not
|
||||
// do that, they assume that cache entry is resolved already.
|
||||
-void VM_EnhancedRedefineClasses::unpatch_bytecode(Method* method) {
|
||||
- RawBytecodeStream bcs(method);
|
||||
+void VM_EnhancedRedefineClasses::unpatch_bytecode(Method* method, TRAPS) {
|
||||
+ RawBytecodeStream bcs(methodHandle(THREAD, method));
|
||||
Bytecodes::Code code;
|
||||
Bytecodes::Code java_code;
|
||||
while (!bcs.is_last_bytecode()) {
|
||||
@@ -1454,11 +1473,11 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
|
||||
HandleMark hm(_thread);
|
||||
InstanceKlass *ik = InstanceKlass::cast(k);
|
||||
|
||||
- constantPoolHandle other_cp = constantPoolHandle(ik->constants());
|
||||
+ constantPoolHandle other_cp = constantPoolHandle(_thread, ik->constants());
|
||||
|
||||
// Update host klass of anonymous classes (for example, produced by lambdas) to newest version.
|
||||
- if (ik->is_anonymous() && ik->host_klass()->new_version() != NULL) {
|
||||
- ik->set_host_klass(InstanceKlass::cast(ik->host_klass()->newest_version()));
|
||||
+ if (ik->is_unsafe_anonymous() && ik->unsafe_anonymous_host()->new_version() != NULL) {
|
||||
+ ik->set_unsafe_anonymous_host(InstanceKlass::cast(ik->unsafe_anonymous_host()->newest_version()));
|
||||
}
|
||||
|
||||
// Update implementor if there is only one, in this case implementor() can reference old class
|
||||
@@ -1492,7 +1511,18 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
|
||||
|
||||
// If bytecode rewriting is enabled, we also need to unpatch bytecode to force resolution of zeroed entries
|
||||
if (RewriteBytecodes) {
|
||||
- ik->methods_do(unpatch_bytecode);
|
||||
+ ik->methods_do(unpatch_bytecode, _thread);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+u8 VM_EnhancedRedefineClasses::next_id() {
|
||||
+ while (true) {
|
||||
+ u8 id = _id_counter;
|
||||
+ u8 next_id = id + 1;
|
||||
+ u8 result = Atomic::cmpxchg(&_id_counter, id, next_id);
|
||||
+ if (result == id) {
|
||||
+ return next_id;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1512,31 +1542,8 @@ void VM_EnhancedRedefineClasses::MethodDataCleaner::do_klass(Klass* k) {
|
||||
}
|
||||
}
|
||||
|
||||
-void VM_EnhancedRedefineClasses::fix_invoke_method(Method* method) {
|
||||
-
|
||||
- constantPoolHandle other_cp = constantPoolHandle(method->constants());
|
||||
-
|
||||
- for (int i = 0; i < other_cp->length(); i++) {
|
||||
- if (other_cp->tag_at(i).is_klass()) {
|
||||
- Klass* klass = other_cp->resolved_klass_at(i);
|
||||
- if (klass->new_version() != NULL) {
|
||||
- // Constant pool entry points to redefined class -- update to the new version
|
||||
- other_cp->klass_at_put(i, klass->newest_version());
|
||||
- }
|
||||
- assert(other_cp->resolved_klass_at(i)->new_version() == NULL, "Must be new klass!");
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- ConstantPoolCache* cp_cache = other_cp->cache();
|
||||
- if (cp_cache != NULL) {
|
||||
- cp_cache->clear_entries();
|
||||
- }
|
||||
-
|
||||
-}
|
||||
-
|
||||
|
||||
-
|
||||
-void VM_EnhancedRedefineClasses::update_jmethod_ids() {
|
||||
+void VM_EnhancedRedefineClasses::update_jmethod_ids(TRAPS) {
|
||||
for (int j = 0; j < _matching_methods_length; ++j) {
|
||||
Method* old_method = _matching_old_methods[j];
|
||||
jmethodID jmid = old_method->find_jmethod_id_or_null();
|
||||
@@ -1547,10 +1554,10 @@ void VM_EnhancedRedefineClasses::update_jmethod_ids() {
|
||||
|
||||
if (jmid != NULL) {
|
||||
// There is a jmethodID, change it to point to the new method
|
||||
- methodHandle new_method_h(_matching_new_methods[j]);
|
||||
+ methodHandle new_method_h(THREAD, _matching_new_methods[j]);
|
||||
|
||||
if (old_method->new_version() == NULL) {
|
||||
- methodHandle old_method_h(_matching_old_methods[j]);
|
||||
+ methodHandle old_method_h(THREAD, _matching_old_methods[j]);
|
||||
jmethodID new_jmethod_id = Method::make_jmethod_id(old_method_h->method_holder()->class_loader_data(), old_method_h());
|
||||
bool result = InstanceKlass::cast(old_method_h->method_holder())->update_jmethod_id(old_method_h(), new_jmethod_id);
|
||||
} else {
|
||||
@@ -1887,7 +1894,7 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
|
||||
|
||||
// track number of methods that are EMCP for add_previous_version() call below
|
||||
check_methods_and_mark_as_obsolete();
|
||||
- update_jmethod_ids();
|
||||
+ update_jmethod_ids(THREAD);
|
||||
|
||||
_any_class_has_resolved_methods = the_class->has_resolved_methods() || _any_class_has_resolved_methods;
|
||||
|
||||
@@ -2119,12 +2126,12 @@ jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
|
||||
|
||||
Handle protection_domain(THREAD, klass->protection_domain());
|
||||
|
||||
+ ClassLoadInfo cl_info(protection_domain);
|
||||
+
|
||||
ClassFileParser parser(&st,
|
||||
klass->name(),
|
||||
klass->class_loader_data(),
|
||||
- protection_domain,
|
||||
- NULL, // host_klass
|
||||
- NULL, // cp_patches
|
||||
+ &cl_info,
|
||||
ClassFileParser::INTERNAL, // publicity level
|
||||
true,
|
||||
THREAD);
|
||||
@@ -2134,7 +2141,7 @@ jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
|
||||
links.append(KlassPair(super_klass, klass));
|
||||
}
|
||||
|
||||
- Array<Klass*>* local_interfaces = parser.local_interfaces();
|
||||
+ Array<InstanceKlass*>* local_interfaces = parser.local_interfaces();
|
||||
for (int j = 0; j < local_interfaces->length(); j++) {
|
||||
Klass* iface = local_interfaces->at(j);
|
||||
if (iface != NULL && _affected_klasses->contains(iface)) {
|
||||
@@ -2157,7 +2164,7 @@ jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
|
||||
links.append(KlassPair(super_klass, klass));
|
||||
}
|
||||
|
||||
- Array<Klass*>* local_interfaces = klass->local_interfaces();
|
||||
+ Array<InstanceKlass*>* local_interfaces = klass->local_interfaces();
|
||||
for (int j = 0; j < local_interfaces->length(); j++) {
|
||||
Klass* interfaceKlass = local_interfaces->at(j);
|
||||
if (_affected_klasses->contains(interfaceKlass)) {
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
index 4c0412d343d..0066088b3b0 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "oops/objArrayOop.hpp"
|
||||
-#include "gc/shared/vmGCOperations.hpp"
|
||||
+#include "gc/shared/gcVMOperations.hpp"
|
||||
#include "../../../java.base/unix/native/include/jni_md.h"
|
||||
|
||||
//
|
||||
@@ -59,6 +59,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
static int _deleted_methods_length;
|
||||
static int _added_methods_length;
|
||||
static Klass* _the_class_oop;
|
||||
+ static u8 _id_counter;
|
||||
|
||||
// The instance fields are used to pass information from
|
||||
// doit_prologue() to doit() and doit_epilogue().
|
||||
@@ -91,6 +92,9 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
elapsedTimer _timer_heap_iterate;
|
||||
elapsedTimer _timer_heap_full_gc;
|
||||
|
||||
+ // Redefinition id used by JFR
|
||||
+ u8 _id;
|
||||
+
|
||||
// These routines are roughly in call order unless otherwise noted.
|
||||
|
||||
// Load and link new classes (either redefined or affected by redefinition - subclass, ...)
|
||||
@@ -118,15 +122,14 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
static void mark_as_scavengable(nmethod* nm);
|
||||
static void unregister_nmethod_g1(nmethod* nm);
|
||||
static void register_nmethod_g1(nmethod* nm);
|
||||
- static void unpatch_bytecode(Method* method);
|
||||
- static void fix_invoke_method(Method* method);
|
||||
+ static void unpatch_bytecode(Method* method, TRAPS);
|
||||
|
||||
// Figure out which new methods match old methods in name and signature,
|
||||
// which methods have been added, and which are no longer present
|
||||
void compute_added_deleted_matching_methods();
|
||||
|
||||
// Change jmethodIDs to point to the new methods
|
||||
- void update_jmethod_ids();
|
||||
+ void update_jmethod_ids(TRAPS);
|
||||
|
||||
// marking methods as old and/or obsolete
|
||||
void check_methods_and_mark_as_obsolete();
|
||||
@@ -141,6 +144,8 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
|
||||
void flush_dependent_code(InstanceKlass* k_h, TRAPS);
|
||||
|
||||
+ u8 next_id();
|
||||
+
|
||||
static void check_class(InstanceKlass* k_oop, TRAPS);
|
||||
|
||||
static void dump_methods();
|
||||
@@ -181,6 +186,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
|
||||
bool allow_nested_vm_operations() const { return true; }
|
||||
jvmtiError check_error() { return _res; }
|
||||
+ u8 id() { return _id; }
|
||||
|
||||
// Modifiable test must be shared between IsModifiableClass query
|
||||
// and redefine implementation
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp
|
||||
index b6838ac034d..fba0f48abd7 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnv.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp
|
||||
@@ -456,20 +456,23 @@ JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
|
||||
|
||||
EventRetransformClasses event;
|
||||
jvmtiError error;
|
||||
+ u8 op_id;
|
||||
|
||||
if (AllowEnhancedClassRedefinition) {
|
||||
MutexLocker sd_mutex(EnhancedRedefineClasses_lock);
|
||||
VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
|
||||
VMThread::execute(&op);
|
||||
+ op_id = op.id();
|
||||
error = (op.check_error());
|
||||
} else {
|
||||
VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
|
||||
VMThread::execute(&op);
|
||||
+ op_id = op.id();
|
||||
error = op.check_error();
|
||||
}
|
||||
if (error == JVMTI_ERROR_NONE) {
|
||||
event.set_classCount(class_count);
|
||||
- event.set_redefinitionId(op.id());
|
||||
+ event.set_redefinitionId(op_id);
|
||||
event.commit();
|
||||
}
|
||||
return error;
|
||||
@@ -484,19 +487,23 @@ JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_de
|
||||
EventRedefineClasses event;
|
||||
jvmtiError error;
|
||||
|
||||
+ u8 op_id;
|
||||
+
|
||||
if (AllowEnhancedClassRedefinition) {
|
||||
MutexLocker sd_mutex(EnhancedRedefineClasses_lock);
|
||||
VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
|
||||
VMThread::execute(&op);
|
||||
+ op_id = op.id();
|
||||
error = (op.check_error());
|
||||
} else {
|
||||
VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
|
||||
VMThread::execute(&op);
|
||||
+ op_id = op.id();
|
||||
error = op.check_error();
|
||||
}
|
||||
if (error == JVMTI_ERROR_NONE) {
|
||||
event.set_classCount(class_count);
|
||||
- event.set_redefinitionId(op.id());
|
||||
+ event.set_redefinitionId(op_id);
|
||||
event.commit();
|
||||
}
|
||||
return error;
|
||||
diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
|
||||
index a7840848e10..346eac7c431 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
|
||||
@@ -1271,6 +1271,7 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
|
||||
the_class_loader,
|
||||
&st,
|
||||
cl_info,
|
||||
+ NULL,
|
||||
THREAD);
|
||||
// Clear class_being_redefined just to be sure.
|
||||
state->clear_class_being_redefined();
|
||||
diff --git a/src/hotspot/share/prims/methodHandles.hpp b/src/hotspot/share/prims/methodHandles.hpp
|
||||
index 54f36202a5f..917d31efd77 100644
|
||||
--- a/src/hotspot/share/prims/methodHandles.hpp
|
||||
+++ b/src/hotspot/share/prims/methodHandles.hpp
|
||||
@@ -180,6 +180,9 @@ public:
|
||||
assert(ref_kind_is_valid(ref_kind), "");
|
||||
return (ref_kind & 1) != 0;
|
||||
}
|
||||
+ static bool ref_kind_is_static(int ref_kind) {
|
||||
+ return !ref_kind_has_receiver(ref_kind) && (ref_kind != JVM_REF_newInvokeSpecial);
|
||||
+ }
|
||||
|
||||
static int ref_kind_to_flags(int ref_kind);
|
||||
|
||||
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
|
||||
index d05a2893498..3a92b8869dc 100644
|
||||
--- a/src/hotspot/share/runtime/arguments.cpp
|
||||
+++ b/src/hotspot/share/runtime/arguments.cpp
|
||||
@@ -2128,13 +2128,15 @@ bool Arguments::check_gc_consistency() {
|
||||
// of collectors.
|
||||
uint i = 0;
|
||||
if (UseSerialGC) i++;
|
||||
- if (UseConcMarkSweepGC) i++;
|
||||
- if (UseParallelGC || UseParallelOldGC) i++;
|
||||
+ if (UseParallelGC) i++;
|
||||
if (UseG1GC) i++;
|
||||
+ if (UseEpsilonGC) i++;
|
||||
+ if (UseZGC) i++;
|
||||
+ if (UseShenandoahGC) i++;
|
||||
if (AllowEnhancedClassRedefinition) {
|
||||
// Must use serial GC. This limitation applies because the instance size changing GC modifications
|
||||
// are only built into the mark and compact algorithm.
|
||||
- if ((!UseSerialGC && !UseG1GC) && i >= 1) {
|
||||
+ if (!UseSerialGC && !UseG1GC && i >= 1) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Must use the Serial or G1 GC with enhanced class redefinition.\n");
|
||||
return false;
|
||||
@@ -4494,18 +4496,18 @@ void Arguments::setup_hotswap_agent() {
|
||||
|
||||
// TODO: open it only for org.hotswap.agent module
|
||||
// Use to access java.lang.reflect.Proxy/proxyCache
|
||||
- create_numbered_property("jdk.module.addopens", "java.base/java.lang=ALL-UNNAMED", addopens_count++);
|
||||
+ create_numbered_module_property("jdk.module.addopens", "java.base/java.lang=ALL-UNNAMED", addopens_count++);
|
||||
// Class of field java.lang.reflect.Proxy/proxyCache
|
||||
- create_numbered_property("jdk.module.addopens", "java.base/jdk.internal.loader=ALL-UNNAMED", addopens_count++);
|
||||
+ create_numbered_module_property("jdk.module.addopens", "java.base/jdk.internal.loader=ALL-UNNAMED", addopens_count++);
|
||||
// Use to access java.io.Reader, java.io.InputStream, java.io.FileInputStream
|
||||
- create_numbered_property("jdk.module.addopens", "java.base/java.io=ALL-UNNAMED", addopens_count++);
|
||||
+ create_numbered_module_property("jdk.module.addopens", "java.base/java.io=ALL-UNNAMED", addopens_count++);
|
||||
// java.beans.Introspector access
|
||||
- create_numbered_property("jdk.module.addopens", "java.desktop/java.beans=ALL-UNNAMED", addopens_count++);
|
||||
+ create_numbered_module_property("jdk.module.addopens", "java.desktop/java.beans=ALL-UNNAMED", addopens_count++);
|
||||
// java.beans.Introspector access
|
||||
- create_numbered_property("jdk.module.addopens", "java.desktop/com.sun.beans=ALL-UNNAMED", addopens_count++);
|
||||
+ create_numbered_module_property("jdk.module.addopens", "java.desktop/com.sun.beans=ALL-UNNAMED", addopens_count++);
|
||||
// com.sun.beans.introspect.ClassInfo access
|
||||
- create_numbered_property("jdk.module.addopens", "java.desktop/com.sun.beans.introspect=ALL-UNNAMED", addopens_count++);
|
||||
+ create_numbered_module_property("jdk.module.addopens", "java.desktop/com.sun.beans.introspect=ALL-UNNAMED", addopens_count++);
|
||||
// com.sun.beans.introspect.util.Cache access
|
||||
- create_numbered_property("jdk.module.addopens", "java.desktop/com.sun.beans.util=ALL-UNNAMED", addopens_count++);
|
||||
+ create_numbered_module_property("jdk.module.addopens", "java.desktop/com.sun.beans.util=ALL-UNNAMED", addopens_count++);
|
||||
|
||||
}
|
||||
diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp
|
||||
index 6f982072909..14a3ed730fe 100644
|
||||
--- a/src/hotspot/share/runtime/mutexLocker.cpp
|
||||
+++ b/src/hotspot/share/runtime/mutexLocker.cpp
|
||||
@@ -287,7 +287,7 @@ void mutex_init() {
|
||||
def(InitCompleted_lock , PaddedMonitor, leaf, true, _safepoint_check_never);
|
||||
def(VtableStubs_lock , PaddedMutex , nonleaf, true, _safepoint_check_never);
|
||||
def(Notify_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always);
|
||||
- def(EnhancedRedefineClasses_lock , PaddedMutex , nonleaf+7, false, Monitor::_safepoint_check_always); // for ensuring that class redefinition is not done in parallel
|
||||
+ def(EnhancedRedefineClasses_lock , PaddedMutex , nonleaf+7, false, _safepoint_check_always); // for ensuring that class redefinition is not done in parallel
|
||||
def(JNICritical_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); // used for JNI critical regions
|
||||
def(AdapterHandlerLibrary_lock , PaddedMutex , nonleaf, true, _safepoint_check_always);
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
25
jb/project/tools/patches/dcevm/0020-dcevm15-G1-fixes.patch
Normal file
25
jb/project/tools/patches/dcevm/0020-dcevm15-G1-fixes.patch
Normal file
@@ -0,0 +1,25 @@
|
||||
From 336cab4f72c6e642e3077ea8d1a4860de33f5a4d Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Tue, 17 Nov 2020 17:40:24 +0100
|
||||
Subject: [PATCH 20/34] dcevm15 - G1 fixes
|
||||
|
||||
---
|
||||
src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
|
||||
index 2f06b9617e4..476728a5d26 100644
|
||||
--- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
|
||||
+++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
|
||||
@@ -240,7 +240,7 @@ void G1FullGCPrepareTask::prepare_serial_compaction_dcevm() {
|
||||
|
||||
// collect remaining, not forwarded rescued oops using serial compact point
|
||||
while (cp->last_rescued_oop() < cp->rescued_oops()->length()) {
|
||||
- HeapRegion* hr = G1CollectedHeap::heap()->new_region(HeapRegion::GrainBytes / HeapWordSize, false, true);
|
||||
+ HeapRegion* hr = G1CollectedHeap::heap()->new_region(HeapRegion::GrainBytes / HeapWordSize, HeapRegionType::Eden, true, G1NUMA::AnyNodeIndex);
|
||||
if (hr == NULL) {
|
||||
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "G1 - not enough of free regions after redefinition.");
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
From cea4e2cca3c37233c728be7235f8f9d8be136cb5 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Tue, 17 Nov 2020 18:52:57 +0100
|
||||
Subject: [PATCH 21/34] dcevm15 - Fix flush dependent code
|
||||
|
||||
---
|
||||
.../prims/jvmtiEnhancedRedefineClasses.cpp | 57 +++++++------------
|
||||
.../prims/jvmtiEnhancedRedefineClasses.hpp | 4 +-
|
||||
2 files changed, 25 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index 619e3988e3a..efaf11e1666 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -508,7 +508,7 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
|
||||
// Deoptimize all compiled code that depends on this class (do only once, because it clears whole cache)
|
||||
// if (_max_redefinition_flags > Klass::ModifyClass) {
|
||||
- flush_dependent_code(NULL, thread);
|
||||
+ flush_dependent_code(thread);
|
||||
// }
|
||||
|
||||
// Adjust constantpool caches for all classes that reference methods of the evolved class.
|
||||
@@ -647,17 +647,8 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
//MethodDataCleaner clean_weak_method_links;
|
||||
//ClassLoaderDataGraph::classes_do(&clean_weak_method_links);
|
||||
|
||||
- // Disable any dependent concurrent compilations
|
||||
- // SystemDictionary::notice_modification();
|
||||
-
|
||||
JvmtiExport::increment_redefinition_count();
|
||||
|
||||
- // Set flag indicating that some invariants are no longer true.
|
||||
- // See jvmtiExport.hpp for detailed explanation.
|
||||
-
|
||||
- // dcevm15: handled by _redefinition_count
|
||||
- // JvmtiExport::set_has_redefined_a_class();
|
||||
-
|
||||
#ifdef PRODUCT
|
||||
if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
|
||||
#endif
|
||||
@@ -1746,6 +1737,18 @@ void VM_EnhancedRedefineClasses::transfer_old_native_function_registrations(Inst
|
||||
transfer.transfer_registrations(_matching_old_methods, _matching_methods_length);
|
||||
}
|
||||
|
||||
+// First step is to walk the code cache for each class redefined and mark
|
||||
+// dependent methods. Wait until all classes are processed to deoptimize everything.
|
||||
+void VM_EnhancedRedefineClasses::mark_dependent_code(InstanceKlass* ik) {
|
||||
+ assert_locked_or_safepoint(Compile_lock);
|
||||
+
|
||||
+ // All dependencies have been recorded from startup or this is a second or
|
||||
+ // subsequent use of RedefineClasses
|
||||
+ if (0 && JvmtiExport::all_dependencies_are_recorded()) {
|
||||
+ CodeCache::mark_for_evol_deoptimization(ik);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// DCEVM - it always deoptimizes everything! (because it is very difficult to find only correct dependencies)
|
||||
// Deoptimize all compiled code that depends on this class.
|
||||
//
|
||||
@@ -1762,33 +1765,21 @@ void VM_EnhancedRedefineClasses::transfer_old_native_function_registrations(Inst
|
||||
// subsequent calls to RedefineClasses need only throw away code
|
||||
// that depends on the class.
|
||||
//
|
||||
-void VM_EnhancedRedefineClasses::flush_dependent_code(InstanceKlass* k_h, TRAPS) {
|
||||
+void VM_EnhancedRedefineClasses::flush_dependent_code(TRAPS) {
|
||||
assert_locked_or_safepoint(Compile_lock);
|
||||
|
||||
// All dependencies have been recorded from startup or this is a second or
|
||||
// subsequent use of RedefineClasses
|
||||
// FIXME: for now, deoptimize all!
|
||||
- if (0 && k_h != NULL && JvmtiExport::all_dependencies_are_recorded()) {
|
||||
- CodeCache::flush_evol_dependents_on(k_h);
|
||||
- Klass* superCl = k_h->super();
|
||||
- // Deoptimize super classes since redefined class can has a new method override
|
||||
- while (superCl != NULL && !superCl->is_redefining()) {
|
||||
- CodeCache::flush_evol_dependents_on(InstanceKlass::cast(superCl));
|
||||
- superCl = superCl->super();
|
||||
+ if (0 && JvmtiExport::all_dependencies_are_recorded()) {
|
||||
+ int deopt = CodeCache::mark_dependents_for_evol_deoptimization();
|
||||
+ log_debug(redefine, class, nmethod)("Marked %d dependent nmethods for deopt", deopt);
|
||||
+ if (deopt != 0) {
|
||||
+ CodeCache::flush_evol_dependents();
|
||||
}
|
||||
} else {
|
||||
- CodeCache::mark_all_nmethods_for_deoptimization();
|
||||
-
|
||||
- ResourceMark rm(THREAD);
|
||||
- DeoptimizationMarker dm;
|
||||
-
|
||||
- // Deoptimize all activations depending on marked nmethods
|
||||
- Deoptimization::deoptimize_dependents();
|
||||
-
|
||||
- // Make the dependent methods not entrant
|
||||
- CodeCache::make_marked_nmethods_not_entrant();
|
||||
-
|
||||
- // From now on we know that the dependency information is complete
|
||||
+ CodeCache::mark_all_nmethods_for_evol_deoptimization();
|
||||
+ CodeCache::flush_evol_dependents();
|
||||
JvmtiExport::set_all_dependencies_are_recorded(true);
|
||||
}
|
||||
}
|
||||
@@ -1881,11 +1872,7 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
|
||||
JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
|
||||
jvmti_breakpoints.clearall_in_class_at_safepoint(the_class);
|
||||
|
||||
- // DCEVM Deoptimization is always for whole java world, call only once after all classes are redefined
|
||||
- // Deoptimize all compiled code that depends on this class
|
||||
-// if (_max_redefinition_flags <= Klass::ModifyClass) {
|
||||
-// flush_dependent_code(the_class, THREAD);
|
||||
-// }
|
||||
+ mark_dependent_code(the_class);
|
||||
|
||||
_old_methods = the_class->methods();
|
||||
_new_methods = new_class->methods();
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
index 0066088b3b0..bd5e7d153be 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
@@ -142,7 +142,9 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
// and in all direct and indirect subclasses.
|
||||
void increment_class_counter(InstanceKlass *ik, TRAPS);
|
||||
|
||||
- void flush_dependent_code(InstanceKlass* k_h, TRAPS);
|
||||
+ void mark_dependent_code(InstanceKlass* ik);
|
||||
+
|
||||
+ void flush_dependent_code(TRAPS);
|
||||
|
||||
u8 next_id();
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
From 4f88dcec830d39452f69d1117729469fdb768a8f Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 22 Nov 2020 12:05:26 +0100
|
||||
Subject: [PATCH 22/34] dcevm15 - fix ResolvedMethodTable
|
||||
|
||||
---
|
||||
src/hotspot/share/classfile/javaClasses.cpp | 5 -
|
||||
src/hotspot/share/classfile/javaClasses.hpp | 1 -
|
||||
.../share/prims/resolvedMethodTable.cpp | 139 +++++++++++-------
|
||||
3 files changed, 84 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
|
||||
index 9b086a241f7..9a627786d0f 100644
|
||||
--- a/src/hotspot/share/classfile/javaClasses.cpp
|
||||
+++ b/src/hotspot/share/classfile/javaClasses.cpp
|
||||
@@ -3996,11 +3996,6 @@ void java_lang_invoke_ResolvedMethodName::set_vmholder(oop resolved_method, oop
|
||||
resolved_method->obj_field_put(_vmholder_offset, holder);
|
||||
}
|
||||
|
||||
-void java_lang_invoke_ResolvedMethodName::set_vmholder_offset(oop resolved_method, Method* m) {
|
||||
- assert(is_instance(resolved_method), "wrong type");
|
||||
- resolved_method->obj_field_put(_vmholder_offset, m->method_holder()->java_mirror());
|
||||
-}
|
||||
-
|
||||
oop java_lang_invoke_ResolvedMethodName::find_resolved_method(const methodHandle& m, TRAPS) {
|
||||
const Method* method = m();
|
||||
|
||||
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
|
||||
index 9abf2e1d105..8f5993b7225 100644
|
||||
--- a/src/hotspot/share/classfile/javaClasses.hpp
|
||||
+++ b/src/hotspot/share/classfile/javaClasses.hpp
|
||||
@@ -1107,7 +1107,6 @@ class java_lang_invoke_ResolvedMethodName : AllStatic {
|
||||
|
||||
static Method* vmtarget(oop resolved_method);
|
||||
static void set_vmtarget(oop resolved_method, Method* method);
|
||||
- static void set_vmholder_offset(oop resolved_method, Method* method);
|
||||
|
||||
static void set_vmholder(oop resolved_method, oop holder);
|
||||
|
||||
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
index eb9fcda44f3..d0f1667b967 100644
|
||||
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
|
||||
@@ -375,6 +375,67 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
+class AdjustMethodEntriesDcevm : public StackObj {
|
||||
+ bool* _trace_name_printed;
|
||||
+ GrowableArray<oop>* _oops_to_add;
|
||||
+public:
|
||||
+ AdjustMethodEntriesDcevm(GrowableArray<oop>* oops_to_add, bool* trace_name_printed) : _trace_name_printed(trace_name_printed), _oops_to_add(oops_to_add) {};
|
||||
+ bool operator()(WeakHandle<vm_resolved_method_table_data>* entry) {
|
||||
+ oop mem_name = entry->peek();
|
||||
+ if (mem_name == NULL) {
|
||||
+ // Removed
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
||||
+
|
||||
+ if (old_method->is_old()) {
|
||||
+
|
||||
+ InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
|
||||
+ Method* newer_method;
|
||||
+
|
||||
+ // Method* new_method;
|
||||
+ if (old_method->is_deleted()) {
|
||||
+ newer_method = Universe::throw_no_such_method_error();
|
||||
+ } else {
|
||||
+ newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
|
||||
+
|
||||
+ log_debug(redefine, class, update)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
|
||||
+
|
||||
+ assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
|
||||
+ assert(newer_method != NULL, "method_with_idnum() should not be NULL");
|
||||
+ assert(old_method != newer_method, "sanity check");
|
||||
+
|
||||
+ Thread* thread = Thread::current();
|
||||
+ ResolvedMethodTableLookup lookup(thread, method_hash(newer_method), newer_method);
|
||||
+ ResolvedMethodGet rmg(thread, newer_method);
|
||||
+
|
||||
+ if (_local_table->get(thread, lookup, rmg)) {
|
||||
+ // old method was already adjusted if new method exists in _the_table
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, newer_method);
|
||||
+ java_lang_invoke_ResolvedMethodName::set_vmholder(mem_name, newer_method->method_holder()->java_mirror());
|
||||
+
|
||||
+ newer_klass->set_has_resolved_methods();
|
||||
+ _oops_to_add->append(mem_name);
|
||||
+
|
||||
+ ResourceMark rm;
|
||||
+ if (!(*_trace_name_printed)) {
|
||||
+ log_debug(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
|
||||
+ *_trace_name_printed = true;
|
||||
+ }
|
||||
+ log_debug(redefine, class, update, constantpool)
|
||||
+ ("ResolvedMethod method update: %s(%s)",
|
||||
+ newer_method->name()->as_C_string(), newer_method->signature()->as_C_string());
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
// It is called at safepoint only for RedefineClasses
|
||||
void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
|
||||
@@ -382,73 +443,41 @@ void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
|
||||
AdjustMethodEntries adjust(trace_name_printed);
|
||||
_local_table->do_safepoint_scan(adjust);
|
||||
}
|
||||
-#endif // INCLUDE_JVMTI
|
||||
|
||||
-// (DCEVM) It is called at safepoint only for RedefineClasses
|
||||
+// It is called at safepoint only for RedefineClasses
|
||||
void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed) {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
|
||||
// For each entry in RMT, change to new method
|
||||
- GrowableArray<oop>* oops_to_add = new GrowableArray<oop>();
|
||||
-
|
||||
- for (int i = 0; i < _the_table->table_size(); ++i) {
|
||||
- for (ResolvedMethodEntry* entry = _the_table->bucket(i);
|
||||
- entry != NULL;
|
||||
- entry = entry->next()) {
|
||||
-
|
||||
- oop mem_name = entry->object_no_keepalive();
|
||||
- // except ones removed
|
||||
- if (mem_name == NULL) {
|
||||
- continue;
|
||||
- }
|
||||
- Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
||||
-
|
||||
- if (old_method->is_old()) {
|
||||
-
|
||||
- InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
|
||||
- Method* newer_method;
|
||||
-
|
||||
- // Method* new_method;
|
||||
- if (old_method->is_deleted()) {
|
||||
- newer_method = Universe::throw_no_such_method_error();
|
||||
- } else {
|
||||
- newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
|
||||
-
|
||||
- log_debug(redefine, class, update)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
|
||||
-
|
||||
- assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
|
||||
- assert(newer_method != NULL, "method_with_idnum() should not be NULL");
|
||||
- assert(old_method != newer_method, "sanity check");
|
||||
-
|
||||
- if (_the_table->lookup(newer_method) != NULL) {
|
||||
- // old method was already adjusted if new method exists in _the_table
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
+ GrowableArray<oop> oops_to_add(0);
|
||||
+ AdjustMethodEntriesDcevm adjust(&oops_to_add, trace_name_printed);
|
||||
+ _local_table->do_safepoint_scan(adjust);
|
||||
+ Thread* thread = Thread::current();
|
||||
+ for (int i = 0; i < oops_to_add.length(); i++) {
|
||||
+ oop mem_name = oops_to_add.at(i);
|
||||
+ Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
||||
|
||||
- java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, newer_method);
|
||||
- java_lang_invoke_ResolvedMethodName::set_vmholder_offset(mem_name, newer_method);
|
||||
+ // The hash table takes ownership of the WeakHandle, even if it's not inserted.
|
||||
|
||||
- newer_klass->set_has_resolved_methods();
|
||||
- oops_to_add->append(mem_name);
|
||||
+ ResolvedMethodTableLookup lookup(thread, method_hash(method), method);
|
||||
+ ResolvedMethodGet rmg(thread, method);
|
||||
|
||||
- ResourceMark rm;
|
||||
- if (!(*trace_name_printed)) {
|
||||
- log_debug(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
|
||||
- *trace_name_printed = true;
|
||||
- }
|
||||
- log_debug(redefine, class, update, constantpool)
|
||||
- ("ResolvedMethod method update: %s(%s)",
|
||||
- newer_method->name()->as_C_string(), newer_method->signature()->as_C_string());
|
||||
+ while (true) {
|
||||
+ if (_local_table->get(thread, lookup, rmg)) {
|
||||
+ break;
|
||||
+ }
|
||||
+ WeakHandle<vm_resolved_method_table_data> wh = WeakHandle<vm_resolved_method_table_data>::create(Handle(thread, mem_name));
|
||||
+ // The hash table takes ownership of the WeakHandle, even if it's not inserted.
|
||||
+ if (_local_table->insert(thread, lookup, wh)) {
|
||||
+ log_insert(method);
|
||||
+ wh.resolve();
|
||||
+ break;
|
||||
}
|
||||
- }
|
||||
- for (int i = 0; i < oops_to_add->length(); i++) {
|
||||
- oop mem_name = oops_to_add->at(i);
|
||||
- Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
|
||||
- _the_table->basic_add(method, Handle(Thread::current(), mem_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+#endif // INCLUDE_JVMTI
|
||||
+
|
||||
// Verification
|
||||
class VerifyResolvedMethod : StackObj {
|
||||
public:
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
From 5379e56465d3d3930ec7ea91b1c64db2cdf70170 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 22 Nov 2020 12:05:50 +0100
|
||||
Subject: [PATCH 23/34] dcevm15 - fix Universe::root_oops_do
|
||||
|
||||
---
|
||||
src/hotspot/share/memory/universe.cpp | 38 +++++++++------------------
|
||||
1 file changed, 12 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
|
||||
index f6e4253b5a5..8dad437bd51 100644
|
||||
--- a/src/hotspot/share/memory/universe.cpp
|
||||
+++ b/src/hotspot/share/memory/universe.cpp
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "gc/shared/gcConfig.hpp"
|
||||
#include "gc/shared/gcLogPrecious.hpp"
|
||||
#include "gc/shared/gcTraceTime.inline.hpp"
|
||||
+#include "gc/shared/weakProcessor.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
@@ -75,6 +76,7 @@
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "runtime/timerTrace.hpp"
|
||||
#include "runtime/vmOperations.hpp"
|
||||
+#include "services/management.hpp"
|
||||
#include "services/memoryService.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
@@ -180,45 +182,29 @@ void Universe::basic_type_classes_do(KlassClosure *closure) {
|
||||
|
||||
// FIXME: (DCEVM) This method should iterate all pointers that are not within heap objects.
|
||||
void Universe::root_oops_do(OopClosure *oopClosure) {
|
||||
-
|
||||
- class AlwaysTrueClosure: public BoolObjectClosure {
|
||||
- public:
|
||||
- void do_object(oop p) { ShouldNotReachHere(); }
|
||||
- bool do_object_b(oop p) { return true; }
|
||||
- };
|
||||
- AlwaysTrueClosure always_true;
|
||||
-
|
||||
Universe::oops_do(oopClosure);
|
||||
// ReferenceProcessor::oops_do(oopClosure); (tw) check why no longer there
|
||||
JNIHandles::oops_do(oopClosure); // Global (strong) JNI handles
|
||||
Threads::oops_do(oopClosure, NULL);
|
||||
ObjectSynchronizer::oops_do(oopClosure);
|
||||
- // TODO: review, flat profiler was removed in j10
|
||||
- // FlatProfiler::oops_do(oopClosure);
|
||||
- JvmtiExport::oops_do(oopClosure);
|
||||
+ // (DCEVM) TODO: Check if this is correct?
|
||||
+ Management::oops_do(oopClosure);
|
||||
+ OopStorageSet::vm_global()->oops_do(oopClosure);
|
||||
+ CLDToOopClosure cld_closure(oopClosure, ClassLoaderData::_claim_none);
|
||||
+ ClassLoaderDataGraph::cld_do(&cld_closure);
|
||||
|
||||
// Now adjust pointers in remaining weak roots. (All of which should
|
||||
// have been cleared if they pointed to non-surviving objects.)
|
||||
// Global (weak) JNI handles
|
||||
- JNIHandles::weak_oops_do(&always_true, oopClosure);
|
||||
+ WeakProcessor::oops_do(oopClosure);
|
||||
|
||||
CodeBlobToOopClosure blobClosure(oopClosure, CodeBlobToOopClosure::FixRelocations);
|
||||
CodeCache::blobs_do(&blobClosure);
|
||||
- StringTable::oops_do(oopClosure);
|
||||
+ AOT_ONLY(AOTLoader::oops_do(oopClosure);)
|
||||
+ // StringTable::oops_do was removed in j15
|
||||
+ // StringTable::oops_do(oopClosure);
|
||||
|
||||
- // (DCEVM) TODO: Check if this is correct?
|
||||
- //CodeCache::scavenge_root_nmethods_oops_do(oopClosure);
|
||||
- //Management::oops_do(oopClosure);
|
||||
- //ref_processor()->weak_oops_do(&oopClosure);
|
||||
- //PSScavenge::reference_processor()->weak_oops_do(&oopClosure);
|
||||
-
|
||||
-#if INCLUDE_AOT
|
||||
- if (UseAOT) {
|
||||
- AOTLoader::oops_do(oopClosure);
|
||||
- }
|
||||
-#endif
|
||||
- // SO_AllClasses
|
||||
- SystemDictionary::oops_do(oopClosure);
|
||||
+ // PSScavenge::reference_processor()->weak_oops_do(oopClosure);
|
||||
}
|
||||
|
||||
void Universe::oops_do(OopClosure* f) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
From c6ea68e66d37d70739f7b0ee74131322b4526a68 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 22 Nov 2020 12:03:32 +0100
|
||||
Subject: [PATCH 24/34] Cleanup dcevm comments
|
||||
|
||||
---
|
||||
src/hotspot/share/classfile/classLoaderDataGraph.hpp | 2 +-
|
||||
src/hotspot/share/classfile/systemDictionary.hpp | 2 +-
|
||||
src/hotspot/share/gc/shared/gcConfig.cpp | 2 +-
|
||||
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp | 2 +-
|
||||
4 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.hpp b/src/hotspot/share/classfile/classLoaderDataGraph.hpp
|
||||
index f380aa3fa34..8ce94cccb47 100644
|
||||
--- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp
|
||||
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp
|
||||
@@ -104,7 +104,7 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
|
||||
static void dictionary_classes_do(KlassClosure* klass_closure);
|
||||
|
||||
- // Enhanced class redefinition
|
||||
+ // (DCEVM) Enhanced class redefinition
|
||||
static void rollback_redefinition();
|
||||
|
||||
// VM_CounterDecay iteration support
|
||||
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp
|
||||
index 931e655d631..1019dbd0d04 100644
|
||||
--- a/src/hotspot/share/classfile/systemDictionary.hpp
|
||||
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
|
||||
@@ -455,7 +455,7 @@ public:
|
||||
static bool is_well_known_klass(Symbol* class_name);
|
||||
#endif
|
||||
|
||||
- // Enhanced class redefinition
|
||||
+ // (DCEVM) Enhanced class redefinition
|
||||
static void remove_from_hierarchy(InstanceKlass* k);
|
||||
static void update_constraints_after_redefinition();
|
||||
|
||||
diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp
|
||||
index 5c1a09390f1..23fbf715378 100644
|
||||
--- a/src/hotspot/share/gc/shared/gcConfig.cpp
|
||||
+++ b/src/hotspot/share/gc/shared/gcConfig.cpp
|
||||
@@ -99,7 +99,7 @@ void GCConfig::fail_if_non_included_gc_is_selected() {
|
||||
|
||||
void GCConfig::select_gc_ergonomically() {
|
||||
if (AllowEnhancedClassRedefinition && !UseG1GC) {
|
||||
- // Enhanced class redefinition only supports serial GC at the moment
|
||||
+ // (DCEVM) Enhanced class redefinition only supports serial GC at the moment
|
||||
FLAG_SET_ERGO(UseSerialGC, true);
|
||||
} else if (os::is_server_class_machine()) {
|
||||
#if INCLUDE_G1GC
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
index bd5e7d153be..5de375fb888 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
|
||||
@@ -78,7 +78,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
|
||||
// have any entries.
|
||||
bool _any_class_has_resolved_methods;
|
||||
|
||||
- // Enhanced class redefinition, affected klasses contain all classes which should be redefined
|
||||
+ // (DCEVM) Enhanced class redefinition, affected klasses contain all classes which should be redefined
|
||||
// either because of redefine, class hierarchy or interface change
|
||||
GrowableArray<Klass*>* _affected_klasses;
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
From 507d97966c7145d0ae2533459cc504c7b0d6d5b6 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 22 Nov 2020 18:49:05 +0100
|
||||
Subject: [PATCH 25/34] Fix cpCache in not AllowEnhancedClassRedefinition mode
|
||||
|
||||
---
|
||||
src/hotspot/share/oops/cpCache.hpp | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/oops/cpCache.hpp b/src/hotspot/share/oops/cpCache.hpp
|
||||
index 121a13b1dda..64dcf6223f5 100644
|
||||
--- a/src/hotspot/share/oops/cpCache.hpp
|
||||
+++ b/src/hotspot/share/oops/cpCache.hpp
|
||||
@@ -148,13 +148,13 @@ class ConstantPoolCacheEntry {
|
||||
void set_bytecode_2(Bytecodes::Code code);
|
||||
void set_f1(Metadata* f1) {
|
||||
Metadata* existing_f1 = _f1; // read once
|
||||
- //assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change");
|
||||
+ assert(AllowEnhancedClassRedefinition || existing_f1 == NULL || existing_f1 == f1, "illegal field change");
|
||||
_f1 = f1;
|
||||
}
|
||||
void release_set_f1(Metadata* f1);
|
||||
void set_f2(intx f2) {
|
||||
intx existing_f2 = _f2; // read once
|
||||
- //assert(existing_f2 == 0 || existing_f2 == f2, "illegal field change");
|
||||
+ assert(AllowEnhancedClassRedefinition || existing_f2 == 0 || existing_f2 == f2, "illegal field change");
|
||||
_f2 = f2;
|
||||
}
|
||||
void set_f2_as_vfinal_method(Method* f2) {
|
||||
@@ -215,7 +215,9 @@ class ConstantPoolCacheEntry {
|
||||
void initialize_resolved_reference_index(int ref_index) {
|
||||
assert(_f2 == 0, "set once"); // note: ref_index might be zero also
|
||||
_f2 = ref_index;
|
||||
- _flags = 1 << is_resolved_ref_shift;
|
||||
+ if (AllowEnhancedClassRedefinition) {
|
||||
+ _flags = 1 << is_resolved_ref_shift;
|
||||
+ }
|
||||
}
|
||||
|
||||
void set_field( // sets entry to resolved field state
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From b516b615c20fafa2094dfb9f4cb08245b26418d0 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 22 Nov 2020 19:51:46 +0100
|
||||
Subject: [PATCH 26/34] dcevm15 - add ClassLoaderDataGraph_lock on
|
||||
ClassLoaderDataGraph::classes_do
|
||||
|
||||
ClassLoaderDataGraph::classes_do need safepoint or lock,
|
||||
find_sorted_affected_classes is not in safepoint therefore it must be
|
||||
locked
|
||||
---
|
||||
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index efaf11e1666..197e1c0029f 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -2063,7 +2063,10 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
|
||||
AffectedKlassClosure closure(_affected_klasses);
|
||||
// Updated in j10, from original SystemDictionary::classes_do
|
||||
|
||||
- ClassLoaderDataGraph::classes_do(&closure);
|
||||
+ {
|
||||
+ MutexLocker mcld(ClassLoaderDataGraph_lock);
|
||||
+ ClassLoaderDataGraph::classes_do(&closure);
|
||||
+ }
|
||||
//ClassLoaderDataGraph::dictionary_classes_do(&closure);
|
||||
|
||||
log_trace(redefine, class, load)("%d classes affected", _affected_klasses->length());
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
From c6498946006879314bdc6218ee72da5d9c88f237 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sat, 28 Nov 2020 19:29:42 +0100
|
||||
Subject: [PATCH 27/34] dcevm15 - check if has_nestmate_access_to has newest
|
||||
host class
|
||||
|
||||
---
|
||||
src/hotspot/share/oops/instanceKlass.cpp | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
|
||||
index 5e40d78a87e..1d9623f2446 100644
|
||||
--- a/src/hotspot/share/oops/instanceKlass.cpp
|
||||
+++ b/src/hotspot/share/oops/instanceKlass.cpp
|
||||
@@ -445,6 +445,11 @@ bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+ if (AllowEnhancedClassRedefinition) {
|
||||
+ // TODO: (DCEVM) check if it correct. It fix problems with lambdas (hidden)
|
||||
+ cur_host = InstanceKlass::cast(cur_host->newest_version());
|
||||
+ }
|
||||
+
|
||||
Klass* k_nest_host = k->nest_host(CHECK_false);
|
||||
if (k_nest_host == NULL) {
|
||||
return false;
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
From 86c27155386c1c40642c99c63a242d1f5d8601a5 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sat, 28 Nov 2020 19:31:08 +0100
|
||||
Subject: [PATCH 28/34] Remove unused fieldType
|
||||
|
||||
---
|
||||
src/hotspot/share/classfile/vmSymbols.hpp | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
|
||||
index 6a3b234b222..eb06684a288 100644
|
||||
--- a/src/hotspot/share/classfile/vmSymbols.hpp
|
||||
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
|
||||
@@ -465,7 +465,6 @@
|
||||
template(static_offset_name, "staticOffset") \
|
||||
template(static_base_name, "staticBase") \
|
||||
template(field_offset_name, "fieldOffset") \
|
||||
- template(field_type_name, "fieldType") \
|
||||
\
|
||||
/* name symbols needed by intrinsics */ \
|
||||
\
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From 025d0d2903963fb79f83cf0d90418783d3ef6813 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 29 Nov 2020 17:18:16 +0100
|
||||
Subject: [PATCH 29/34] mark_as_scavengable only alive methods
|
||||
|
||||
---
|
||||
.../share/prims/jvmtiEnhancedRedefineClasses.cpp | 14 ++++++++------
|
||||
1 file changed, 8 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index 197e1c0029f..e00fac1f693 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -223,19 +223,21 @@ class FieldCopier : public FieldClosure {
|
||||
|
||||
// TODO: review...
|
||||
void VM_EnhancedRedefineClasses::mark_as_scavengable(nmethod* nm) {
|
||||
- ScavengableNMethods::register_nmethod(nm);
|
||||
+ if (nm->is_alive()) {
|
||||
+ ScavengableNMethods::register_nmethod(nm);
|
||||
+ }
|
||||
}
|
||||
|
||||
void VM_EnhancedRedefineClasses::unregister_nmethod_g1(nmethod* nm) {
|
||||
// It should work not only for G1 but also for another GCs, but this way is safer now
|
||||
- if (!nm->is_zombie() && !nm->is_unloaded()) {
|
||||
+ if (nm->is_alive()) {
|
||||
Universe::heap()->unregister_nmethod(nm);
|
||||
}
|
||||
}
|
||||
|
||||
void VM_EnhancedRedefineClasses::register_nmethod_g1(nmethod* nm) {
|
||||
// It should work not only for G1 but also for another GCs, but this way is safer now
|
||||
- if (!nm->is_zombie() && !nm->is_unloaded()) {
|
||||
+ if (nm->is_alive()) {
|
||||
Universe::heap()->register_nmethod(nm);
|
||||
}
|
||||
}
|
||||
@@ -511,9 +513,9 @@ void VM_EnhancedRedefineClasses::doit() {
|
||||
flush_dependent_code(thread);
|
||||
// }
|
||||
|
||||
- // Adjust constantpool caches for all classes that reference methods of the evolved class.
|
||||
- ClearCpoolCacheAndUnpatch clear_cpool_cache(thread);
|
||||
- ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
|
||||
+ // Adjust constantpool caches for all classes that reference methods of the evolved class.
|
||||
+ ClearCpoolCacheAndUnpatch clear_cpool_cache(thread);
|
||||
+ ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
|
||||
|
||||
// JSR-292 support
|
||||
if (_any_class_has_resolved_methods) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
From 27aabfefe7d799545049bb81ba19d4ed2ff6379c Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 29 Nov 2020 17:20:11 +0100
|
||||
Subject: [PATCH 30/34] dcevm15 - lock on
|
||||
ClassLoaderDataGraph::rollback_redefinition
|
||||
|
||||
rollback is not in safepoint, therefore must be locked
|
||||
---
|
||||
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index e00fac1f693..db5fb1c472b 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -1382,7 +1382,9 @@ void VM_EnhancedRedefineClasses::calculate_instance_update_information(Klass* ne
|
||||
// Rollback all changes - clear new classes from the system dictionary, return old classes to directory, free memory.
|
||||
void VM_EnhancedRedefineClasses::rollback() {
|
||||
log_info(redefine, class, load)("Rolling back redefinition, result=%d", _res);
|
||||
+ ClassLoaderDataGraph_lock->lock();
|
||||
ClassLoaderDataGraph::rollback_redefinition();
|
||||
+ ClassLoaderDataGraph_lock->unlock();
|
||||
|
||||
for (int i = 0; i < _new_classes->length(); i++) {
|
||||
SystemDictionary::remove_from_hierarchy(_new_classes->at(i));
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
From 9b405cb642d5935c39c8dbd522ea2fdecfc29ef3 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 29 Nov 2020 19:59:50 +0100
|
||||
Subject: [PATCH 31/34] ResourceMark in G1IterateObjectClosureTask fixing
|
||||
memory leaks
|
||||
|
||||
G1IterateObjectClosureTask is used only in redefinition full GC run
|
||||
---
|
||||
src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
|
||||
index a29d2dddc2d..2af6df6c1e4 100644
|
||||
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
|
||||
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
|
||||
@@ -2362,6 +2362,9 @@ class G1IterateObjectClosureTask : public AbstractGangTask {
|
||||
_cl(cl), _g1h(g1h), _hrclaimer(g1h->workers()->active_workers()) { }
|
||||
|
||||
virtual void work(uint worker_id) {
|
||||
+ Thread *thread = Thread::current();
|
||||
+ HandleMark hm(thread); // make sure any handles created are deleted
|
||||
+ ResourceMark rm(thread);
|
||||
IterateObjectClosureRegionClosure blk(_cl);
|
||||
_g1h->heap_region_par_iterate_from_worker_offset(&blk, &_hrclaimer, worker_id);
|
||||
}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
From 40fe40884d4efc50864bb3f2dd88f0a2e7122d5a Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 29 Nov 2020 20:05:03 +0100
|
||||
Subject: [PATCH 32/34] dcevm15 - fix hidded classes
|
||||
|
||||
---
|
||||
.../prims/jvmtiEnhancedRedefineClasses.cpp | 41 ++++++++++++++-----
|
||||
1 file changed, 30 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
index db5fb1c472b..590f7fdfafe 100644
|
||||
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
|
||||
@@ -722,7 +722,8 @@ bool VM_EnhancedRedefineClasses::is_modifiable_class(oop klass_mirror) {
|
||||
}
|
||||
|
||||
// Cannot redefine or retransform an anonymous class.
|
||||
- if (InstanceKlass::cast(k)->is_unsafe_anonymous()) {
|
||||
+ // TODO: check if is correct in j15
|
||||
+ if (InstanceKlass::cast(k)->is_unsafe_anonymous() || InstanceKlass::cast(k)->is_hidden()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -808,21 +809,27 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
|
||||
InstanceKlass* k;
|
||||
|
||||
- if (InstanceKlass::cast(the_class)->is_unsafe_anonymous()) {
|
||||
- const InstanceKlass* host_class = the_class->unsafe_anonymous_host();
|
||||
+ if (the_class->is_unsafe_anonymous() || the_class->is_hidden()) {
|
||||
+ InstanceKlass* dynamic_host_class = NULL;
|
||||
+ InstanceKlass* unsafe_anonymous_host = NULL;
|
||||
|
||||
- // Make sure it's the real host class, not another anonymous class.
|
||||
- while (host_class != NULL && host_class->is_unsafe_anonymous()) {
|
||||
- host_class = host_class->unsafe_anonymous_host();
|
||||
+ if (the_class->is_hidden()) {
|
||||
+ log_debug(redefine, class, load)("loading hidden class %s", the_class->name()->as_C_string());
|
||||
+ dynamic_host_class = the_class->nest_host(THREAD);
|
||||
+ }
|
||||
+
|
||||
+ if (the_class->is_unsafe_anonymous()) {
|
||||
+ log_debug(redefine, class, load)("loading usafe anonymous %s", the_class->name()->as_C_string());
|
||||
+ unsafe_anonymous_host = the_class->unsafe_anonymous_host();
|
||||
}
|
||||
|
||||
ClassLoadInfo cl_info(protection_domain,
|
||||
- host_class,
|
||||
- NULL, // dynamic_nest_host
|
||||
+ unsafe_anonymous_host,
|
||||
NULL, // cp_patches
|
||||
+ dynamic_host_class, // dynamic_nest_host
|
||||
Handle(), // classData
|
||||
- false, // is_hidden
|
||||
- false, // is_strong_hidden
|
||||
+ the_class->is_hidden(), // is_hidden
|
||||
+ !the_class->is_non_strong_hidden(), // is_strong_hidden
|
||||
true); // FIXME: check if correct. can_access_vm_annotations
|
||||
|
||||
k = SystemDictionary::parse_stream(the_class_sym,
|
||||
@@ -833,7 +840,17 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
|
||||
THREAD);
|
||||
|
||||
k->class_loader_data()->exchange_holders(the_class->class_loader_data());
|
||||
- the_class->class_loader_data()->inc_keep_alive();
|
||||
+
|
||||
+ if (the_class->is_hidden()) {
|
||||
+ // from jvm_lookup_define_class() (jvm.cpp):
|
||||
+ // The hidden class loader data has been artificially been kept alive to
|
||||
+ // this point. The mirror and any instances of this class have to keep
|
||||
+ // it alive afterwards.
|
||||
+ the_class->class_loader_data()->dec_keep_alive();
|
||||
+ } else {
|
||||
+ the_class->class_loader_data()->inc_keep_alive();
|
||||
+ }
|
||||
+
|
||||
} else {
|
||||
k = SystemDictionary::resolve_from_stream(the_class_sym,
|
||||
the_class_loader,
|
||||
@@ -1475,6 +1492,8 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
|
||||
ik->set_unsafe_anonymous_host(InstanceKlass::cast(ik->unsafe_anonymous_host()->newest_version()));
|
||||
}
|
||||
|
||||
+ // FIXME: check new nest_host for hidden
|
||||
+
|
||||
// Update implementor if there is only one, in this case implementor() can reference old class
|
||||
if (ik->is_interface()) {
|
||||
Klass* implKlass = ik->implementor();
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
From 29920b076b4ad96d85adbce0a1d947e5022ba3ad Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 29 Nov 2020 20:08:57 +0100
|
||||
Subject: [PATCH 33/34] dcevm15 - DON'T clear F2 in CP cache after indy
|
||||
unevolving
|
||||
|
||||
It's not clear why it was cleared in dcevm7-11
|
||||
---
|
||||
src/hotspot/share/oops/cpCache.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp
|
||||
index 79a38dbeff0..650e6fab42d 100644
|
||||
--- a/src/hotspot/share/oops/cpCache.cpp
|
||||
+++ b/src/hotspot/share/oops/cpCache.cpp
|
||||
@@ -650,7 +650,7 @@ void ConstantPoolCacheEntry::clear_entry() {
|
||||
|
||||
if (clearData) {
|
||||
if (!is_resolved_reference()) {
|
||||
- _f2 = 0;
|
||||
+ // _f2 = 0;
|
||||
}
|
||||
// FIXME: (DCEVM) we want to clear flags, but parameter size is actually used
|
||||
// after we return from the method, before entry is re-initialized. So let's
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 1f13b20ab5553182680045b7d7324ff92da7e7f0 Mon Sep 17 00:00:00 2001
|
||||
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
|
||||
Date: Sun, 29 Nov 2020 21:28:06 +0100
|
||||
Subject: [PATCH 34/34] dcevm15 - fix Universe::root_oops_do
|
||||
|
||||
Removed ClassLoaderDataGraph::cld_do was cause of crashes due multiple
|
||||
oop patching. ClassLoaderDataGraph::cld_do replaced in dcevm15
|
||||
previously used and removed SystemDictionary:oops_do
|
||||
---
|
||||
src/hotspot/share/memory/universe.cpp | 11 ++++++++---
|
||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
|
||||
index 8dad437bd51..0199962a684 100644
|
||||
--- a/src/hotspot/share/memory/universe.cpp
|
||||
+++ b/src/hotspot/share/memory/universe.cpp
|
||||
@@ -190,21 +190,26 @@ void Universe::root_oops_do(OopClosure *oopClosure) {
|
||||
// (DCEVM) TODO: Check if this is correct?
|
||||
Management::oops_do(oopClosure);
|
||||
OopStorageSet::vm_global()->oops_do(oopClosure);
|
||||
- CLDToOopClosure cld_closure(oopClosure, ClassLoaderData::_claim_none);
|
||||
- ClassLoaderDataGraph::cld_do(&cld_closure);
|
||||
+ // CLDToOopClosure cld_closure(oopClosure, ClassLoaderData::_claim_none);
|
||||
+ // ClassLoaderDataGraph::cld_do(&cld_closure);
|
||||
|
||||
// Now adjust pointers in remaining weak roots. (All of which should
|
||||
// have been cleared if they pointed to non-surviving objects.)
|
||||
// Global (weak) JNI handles
|
||||
WeakProcessor::oops_do(oopClosure);
|
||||
|
||||
+ JvmtiExport::oops_do(oopClosure);
|
||||
+
|
||||
CodeBlobToOopClosure blobClosure(oopClosure, CodeBlobToOopClosure::FixRelocations);
|
||||
CodeCache::blobs_do(&blobClosure);
|
||||
+
|
||||
AOT_ONLY(AOTLoader::oops_do(oopClosure);)
|
||||
+
|
||||
// StringTable::oops_do was removed in j15
|
||||
// StringTable::oops_do(oopClosure);
|
||||
|
||||
- // PSScavenge::reference_processor()->weak_oops_do(oopClosure);
|
||||
+ // OopStorageSet::vm_global()->oops_do(oopClosure);
|
||||
+
|
||||
}
|
||||
|
||||
void Universe::oops_do(OopClosure* f) {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
147
jb/project/tools/windows/scripts/mkimages_x64.sh
Executable file
147
jb/project/tools/windows/scripts/mkimages_x64.sh
Executable file
@@ -0,0 +1,147 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# The following parameters must be specified:
|
||||
# JBSDK_VERSION - specifies major version of OpenJDK e.g. 11_0_6 (instead of dots '.' underbars "_" are used)
|
||||
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument to configure
|
||||
# build_number - specifies the number of JetBrainsRuntime build
|
||||
# bundle_type - specifies bundle to be built; possible values:
|
||||
# <empty> or nomod - the release bundles without any additional modules (jcef)
|
||||
# jcef - the release bundles with jcef
|
||||
# fd - the fastdebug bundles which also include the jcef module
|
||||
#
|
||||
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
#
|
||||
# $ ./java --version
|
||||
# openjdk 11.0.6 2020-01-14
|
||||
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
|
||||
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
|
||||
#
|
||||
# Environment variables:
|
||||
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
|
||||
# By default JCEF binaries should be located in ./jcef_win_x64
|
||||
|
||||
while getopts ":i?" o; do
|
||||
case "${o}" in
|
||||
i)
|
||||
i="incremental build"
|
||||
INC_BUILD=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
JBSDK_VERSION=$1
|
||||
JDK_BUILD_NUMBER=$2
|
||||
build_number=$3
|
||||
bundle_type=$4
|
||||
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
|
||||
WORK_DIR=$(pwd)
|
||||
JCEF_PATH=${JCEF_PATH:=$WORK_DIR/jcef_win_x64}
|
||||
|
||||
source jb/project/tools/common/scripts/common.sh
|
||||
|
||||
function do_configure {
|
||||
sh ./configure \
|
||||
$WITH_DEBUG_LEVEL \
|
||||
--with-vendor-name="$VENDOR_NAME" \
|
||||
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
|
||||
--with-jvm-features=shenandoahgc \
|
||||
--with-version-pre= \
|
||||
--with-version-build=$JDK_BUILD_NUMBER \
|
||||
--with-version-opt=b${build_number} \
|
||||
--with-toolchain-version=$TOOLCHAIN_VERSION \
|
||||
--with-boot-jdk=$BOOT_JDK \
|
||||
--disable-ccache \
|
||||
--enable-cds=yes || do_exit $?
|
||||
}
|
||||
|
||||
function create_image_bundle {
|
||||
__bundle_name=$1
|
||||
__arch_name=$2
|
||||
__modules_path=$3
|
||||
__modules=$4
|
||||
|
||||
[ "$bundle_type" == "fd" ] && [ "$__arch_name" == "$JBRSDK_BUNDLE" ] && __bundle_name=$__arch_name && fastdebug_infix="fastdebug-"
|
||||
|
||||
echo Running jlink ...
|
||||
${JSDK}/bin/jlink \
|
||||
--module-path $__modules_path --no-man-pages --compress=2 \
|
||||
--add-modules $__modules --output $__arch_name || do_exit $?
|
||||
|
||||
grep -v "^JAVA_VERSION" "$JSDK"/release | grep -v "^MODULES" >> $__arch_name/release
|
||||
if [ "$__arch_name" == "$JBRSDK_BUNDLE" ]; then
|
||||
sed 's/JBR/JBRSDK/g' $__arch_name/release > release
|
||||
mv release $__arch_name/release
|
||||
copy_jmods "$__modules" "$__modules_path" "$__arch_name"/jmods
|
||||
fi
|
||||
}
|
||||
|
||||
WITH_DEBUG_LEVEL="--with-debug-level=release"
|
||||
RELEASE_NAME=windows-x86_64-server-release
|
||||
|
||||
case "$bundle_type" in
|
||||
"jcef")
|
||||
do_reset_changes=0
|
||||
;;
|
||||
"dcevm")
|
||||
HEAD_REVISION=$(git rev-parse HEAD)
|
||||
git am jb/project/tools/patches/dcevm/*.patch || do_exit $?
|
||||
do_reset_dcevm=0
|
||||
do_reset_changes=0
|
||||
;;
|
||||
"nomod" | "")
|
||||
bundle_type=""
|
||||
;;
|
||||
"fd")
|
||||
do_reset_changes=0
|
||||
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
|
||||
RELEASE_NAME=windows-x86_64-server-fastdebug
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$INC_BUILD" ]; then
|
||||
do_configure || do_exit $?
|
||||
if [ -z "$bundle_type" ]; then
|
||||
make LOG=info CONF=$RELEASE_NAME clean images test-image || do_exit $?
|
||||
else
|
||||
make LOG=info CONF=$RELEASE_NAME clean images || do_exit $?
|
||||
fi
|
||||
else
|
||||
if [ -z "$bundle_type" ]; then
|
||||
make LOG=info CONF=$RELEASE_NAME images test-image || do_exit $?
|
||||
else
|
||||
make LOG=info CONF=$RELEASE_NAME images || do_exit $?
|
||||
fi
|
||||
fi
|
||||
|
||||
IMAGES_DIR=build/$RELEASE_NAME/images
|
||||
JSDK=$IMAGES_DIR/jdk
|
||||
JSDK_MODS_DIR=$IMAGES_DIR/jmods
|
||||
JBRSDK_BUNDLE=jbrsdk
|
||||
|
||||
where cygpath
|
||||
if [ $? -eq 0 ]; then
|
||||
JCEF_PATH="$(cygpath -w $JCEF_PATH | sed 's/\\/\//g')"
|
||||
fi
|
||||
|
||||
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ]; then
|
||||
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
|
||||
update_jsdk_mods "$JSDK" "$JCEF_PATH"/jmods "$JSDK"/jmods "$JSDK_MODS_DIR" || do_exit $?
|
||||
cp $JCEF_PATH/jmods/* ${JSDK_MODS_DIR} # $JSDK/jmods is not unchanged
|
||||
|
||||
jbr_name_postfix="_${bundle_type}"
|
||||
fi
|
||||
|
||||
# create runtime image bundle
|
||||
modules=$(xargs < modules.list | sed s/" "//g) || do_exit $?
|
||||
create_image_bundle "jbr${jbr_name_postfix}" "jbr" $JSDK_MODS_DIR "$modules" || do_exit $?
|
||||
|
||||
# create sdk image bundle
|
||||
modules=$(cat ${JSDK}/release | grep MODULES | sed s/MODULES=//g | sed s/' '/','/g | sed s/\"//g | sed s/\\r//g | sed s/\\n//g)
|
||||
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
|
||||
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
|
||||
fi
|
||||
create_image_bundle "$JBRSDK_BUNDLE${jbr_name_postfix}" "$JBRSDK_BUNDLE" "$JSDK_MODS_DIR" "$modules" || do_exit $?
|
||||
|
||||
do_exit 0
|
||||
62
jb/project/tools/windows/scripts/mkimages_x86.sh
Executable file
62
jb/project/tools/windows/scripts/mkimages_x86.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# The following parameters must be specified:
|
||||
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
|
||||
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
|
||||
# build_number - specifies the number of JetBrainsRuntime build
|
||||
#
|
||||
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
#
|
||||
# $ ./java --version
|
||||
# openjdk 11.0.6 2020-01-14
|
||||
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
|
||||
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
|
||||
#
|
||||
|
||||
JBSDK_VERSION=$1
|
||||
JDK_BUILD_NUMBER=$2
|
||||
build_number=$3
|
||||
|
||||
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
|
||||
|
||||
source jb/project/tools/common/scripts/common.sh
|
||||
|
||||
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
|
||||
WORK_DIR=$(pwd)
|
||||
|
||||
[ -z "$bundle_type" ] && (git apply -p0 < jb/project/tools/patches/exclude_jcef_module.patch || exit $?)
|
||||
|
||||
PATH="/usr/local/bin:/usr/bin:${PATH}"
|
||||
./configure \
|
||||
--with-target-bits=32 \
|
||||
--with-vendor-name="${VENDOR_NAME}" \
|
||||
--with-vendor-version-string="${VENDOR_VERSION_STRING}" \
|
||||
--with-version-pre= \
|
||||
--with-version-build=${JDK_BUILD_NUMBER} \
|
||||
--with-version-opt=b${build_number} \
|
||||
--with-toolchain-version=${TOOLCHAIN_VERSION} \
|
||||
--with-boot-jdk=${BOOT_JDK} \
|
||||
--disable-ccache \
|
||||
--enable-cds=yes || exit 1
|
||||
make clean CONF=windows-x86-server-release || exit 1
|
||||
make LOG=info images CONF=windows-x86-server-release test-image || exit 1
|
||||
|
||||
JBSDK=${JBRSDK_BASE_NAME}-windows-x86-b${build_number}
|
||||
BASE_DIR=build/windows-x86-server-release/images
|
||||
JSDK=${BASE_DIR}/jdk
|
||||
JBRSDK_BUNDLE=jbrsdk
|
||||
|
||||
rm -rf ${BASE_DIR}/${JBRSDK_BUNDLE} && rsync -a --exclude demo --exclude sample ${JSDK}/ ${JBRSDK_BUNDLE} || exit 1
|
||||
sed 's/JBR/JBRSDK/g' ${JSDK}/release > release
|
||||
mv release ${JBRSDK_BUNDLE}/release
|
||||
|
||||
JBR_BUNDLE=jbr
|
||||
rm -rf ${JBR_BUNDLE}
|
||||
grep -v javafx modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.x86
|
||||
${JSDK}/bin/jlink \
|
||||
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
|
||||
--add-modules $(xargs < modules.list.x86 | sed s/" "//g) --output ${JBR_BUNDLE} || exit $?
|
||||
|
||||
echo Modifying release info ...
|
||||
#grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${JBR_BUNDLE}/release
|
||||
58
jb/project/tools/windows/scripts/pack_x64.sh
Executable file
58
jb/project/tools/windows/scripts/pack_x64.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# The following parameters must be specified:
|
||||
# JBSDK_VERSION - specifies major version of OpenJDK e.g. 11_0_6 (instead of dots '.' underbars "_" are used)
|
||||
# JDK_BUILD_NUMBER - specifies udate release of OpenJDK build or the value of --with-version-build argument to configure
|
||||
# build_number - specifies the number of JetBrainsRuntime build
|
||||
# bundle_type - specifies bundle to be built; possible values:
|
||||
# <empty> or nomod - the bundles without any additional modules (jcef)
|
||||
# jcef - the bundles with jcef
|
||||
# fd - the fastdebug bundles which also include the jcef module
|
||||
#
|
||||
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
|
||||
#
|
||||
# $ ./java --version
|
||||
# openjdk 11.0.6 2020-01-14
|
||||
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
|
||||
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
|
||||
#
|
||||
|
||||
source jb/project/tools/common/scripts/common.sh
|
||||
|
||||
JBSDK_VERSION=$1
|
||||
JDK_BUILD_NUMBER=$2
|
||||
build_number=$3
|
||||
bundle_type=$4
|
||||
|
||||
function pack_jbr {
|
||||
__bundle_name=$1
|
||||
__arch_name=$2
|
||||
|
||||
[ "$bundle_type" == "fd" ] && [ "$__arch_name" == "$JBRSDK_BUNDLE" ] && __bundle_name=$__arch_name && fastdebug_infix="fastdebug-"
|
||||
JBR=${__bundle_name}-${JBSDK_VERSION}-windows-x64-${fastdebug_infix}b${build_number}
|
||||
|
||||
echo Creating $JBR.tar.gz ...
|
||||
|
||||
/usr/bin/tar -czf $JBR.tar.gz -C $BASE_DIR $__arch_name || do_exit $?
|
||||
}
|
||||
|
||||
[ "$bundle_type" == "nomod" ] && bundle_type=""
|
||||
|
||||
JBRSDK_BUNDLE=jbrsdk
|
||||
RELEASE_NAME=windows-x86_64-server-release
|
||||
IMAGES_DIR=build/$RELEASE_NAME/images
|
||||
BASE_DIR=.
|
||||
|
||||
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ]; then
|
||||
jbr_name_postfix="_${bundle_type}"
|
||||
fi
|
||||
|
||||
pack_jbr jbr${jbr_name_postfix} jbr
|
||||
pack_jbr jbrsdk${jbr_name_postfix} jbrsdk
|
||||
|
||||
if [ -z "$bundle_type" ]; then
|
||||
JBRSDK_TEST=$JBRSDK_BUNDLE-$JBSDK_VERSION-windows-test-x64-b$build_number
|
||||
echo Creating $JBRSDK_TEST.tar.gz ...
|
||||
/usr/bin/tar -czf $JBRSDK_TEST.tar.gz -C $IMAGES_DIR --exclude='test/jdk/demos' test || do_exit $?
|
||||
fi
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user