mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2026-01-07 09:01:42 +01:00
Compare commits
360 Commits
jbr17.1122
...
jbr17.1249
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b16741c4e2 | ||
|
|
4270b5d5e4 | ||
|
|
99f479c037 | ||
|
|
0f37369f00 | ||
|
|
4f5094f985 | ||
|
|
d7d8d9b8e4 | ||
|
|
252ec1f0be | ||
|
|
3248ccb203 | ||
|
|
6c6b11d8d5 | ||
|
|
aac4fbae3c | ||
|
|
aaaad6b152 | ||
|
|
b80b620642 | ||
|
|
a86fb87ec1 | ||
|
|
5a462bc4ba | ||
|
|
470857e6ea | ||
|
|
75b06421ff | ||
|
|
54a944b2af | ||
|
|
0c4fe90ff4 | ||
|
|
ec2fac0b5a | ||
|
|
e9aab98a6c | ||
|
|
78c5a56adb | ||
|
|
9bea6a0004 | ||
|
|
93937603b3 | ||
|
|
2f54c24249 | ||
|
|
2fa63cd0bc | ||
|
|
2933ea89f0 | ||
|
|
3c2cbecc64 | ||
|
|
0c3c809646 | ||
|
|
853f700b76 | ||
|
|
cd1d10b4bd | ||
|
|
b9e7fffc5c | ||
|
|
6c6c95f7f0 | ||
|
|
7756d7a9d2 | ||
|
|
83dfcc6e8b | ||
|
|
7be14a878a | ||
|
|
adbb5cc60a | ||
|
|
841963a9be | ||
|
|
d33e29fc2b | ||
|
|
14b8ec25fa | ||
|
|
ef5b549b5a | ||
|
|
d31a706e91 | ||
|
|
57f9dbecdb | ||
|
|
fee7ff0c6c | ||
|
|
e120030e90 | ||
|
|
20468cf28b | ||
|
|
c771ad6ad3 | ||
|
|
9403395d26 | ||
|
|
0eaafd1262 | ||
|
|
0460118960 | ||
|
|
ea2c4bfc83 | ||
|
|
7af653070f | ||
|
|
5befaea6af | ||
|
|
b150e0e6ef | ||
|
|
4ec4e665e6 | ||
|
|
91573abaab | ||
|
|
e9b0b6c854 | ||
|
|
2b3ac6256c | ||
|
|
80c0dca4e8 | ||
|
|
42425fcd47 | ||
|
|
78c7a4d461 | ||
|
|
97a161e87c | ||
|
|
ce2f836140 | ||
|
|
d3ed7b8612 | ||
|
|
5cab854d9a | ||
|
|
bd48eb839f | ||
|
|
dcf3eec4db | ||
|
|
e6054b007c | ||
|
|
cda2954a13 | ||
|
|
91573407f6 | ||
|
|
e941459a96 | ||
|
|
c27e9b5b9f | ||
|
|
570a533af2 | ||
|
|
e9d3b2791d | ||
|
|
6652da60ad | ||
|
|
f1267ca967 | ||
|
|
064aaad37b | ||
|
|
2980220059 | ||
|
|
c0d7fd0938 | ||
|
|
c858b523b6 | ||
|
|
4757d06627 | ||
|
|
e64ada25e5 | ||
|
|
c13e01a527 | ||
|
|
dbb2b0da0d | ||
|
|
96b1742580 | ||
|
|
4f16da1d86 | ||
|
|
d6baec1061 | ||
|
|
1b9b0decc6 | ||
|
|
04e3162f10 | ||
|
|
40c37b8123 | ||
|
|
9a5e7e82c0 | ||
|
|
69b831f479 | ||
|
|
7fbe8c6d02 | ||
|
|
4f8105269e | ||
|
|
ffb3e9e316 | ||
|
|
3f1883be14 | ||
|
|
19eb05342f | ||
|
|
bcaaf859ed | ||
|
|
e228e4d82a | ||
|
|
5e3b62f396 | ||
|
|
c9ca4fb26e | ||
|
|
0b353c661f | ||
|
|
5b4ac0d3d6 | ||
|
|
ba33e7a004 | ||
|
|
1df9bd3678 | ||
|
|
957740ba81 | ||
|
|
230a826eee | ||
|
|
a8e573536e | ||
|
|
254da2b498 | ||
|
|
c9780b85cc | ||
|
|
f7f82d66d1 | ||
|
|
c42866954a | ||
|
|
4745843ca3 | ||
|
|
f1f84a54aa | ||
|
|
d9a4791d0d | ||
|
|
3048ec453f | ||
|
|
c59032824a | ||
|
|
53cda2b439 | ||
|
|
263a999560 | ||
|
|
c47fde5b32 | ||
|
|
1577ec0e3b | ||
|
|
559da43f48 | ||
|
|
91794c7d31 | ||
|
|
3216a30641 | ||
|
|
3d8d43cec4 | ||
|
|
36908d2e55 | ||
|
|
42bd9acadb | ||
|
|
514eea56ee | ||
|
|
4b507b21fc | ||
|
|
e68509206d | ||
|
|
d67de872b1 | ||
|
|
20cefd13ed | ||
|
|
bf84ffadbd | ||
|
|
35e6506081 | ||
|
|
c37b8443ec | ||
|
|
adf6a60dc6 | ||
|
|
40b517ce8a | ||
|
|
f103f2fc45 | ||
|
|
543632bb96 | ||
|
|
52c88af7a3 | ||
|
|
e1e097e048 | ||
|
|
af5f6fdaa8 | ||
|
|
73f84e1916 | ||
|
|
b08c2dfe78 | ||
|
|
8f6994c67f | ||
|
|
166c6940f9 | ||
|
|
c4860b7c11 | ||
|
|
a34df011cc | ||
|
|
4e7373b602 | ||
|
|
51cd0eff51 | ||
|
|
9e516548d8 | ||
|
|
9e013bb57a | ||
|
|
c7d8ae1c85 | ||
|
|
c03add1fd8 | ||
|
|
7fbb069279 | ||
|
|
e313dcb5c0 | ||
|
|
4ef434f73b | ||
|
|
ff97b0a986 | ||
|
|
6faa5aad6f | ||
|
|
eb7ce1c0c9 | ||
|
|
ed98f2ae5b | ||
|
|
10800552ce | ||
|
|
080a7c7870 | ||
|
|
eb530b199d | ||
|
|
2f61a16abe | ||
|
|
ba9e613dd5 | ||
|
|
05a8507644 | ||
|
|
acf0e33685 | ||
|
|
68dc583fa1 | ||
|
|
d7fa10f27e | ||
|
|
8aea0088d5 | ||
|
|
2907df4b90 | ||
|
|
9aaad3128f | ||
|
|
63676fda8a | ||
|
|
cdea6017f0 | ||
|
|
e607132564 | ||
|
|
b416ccf40f | ||
|
|
4302b2bbc0 | ||
|
|
f45661f900 | ||
|
|
0bab361fde | ||
|
|
6c26b12173 | ||
|
|
675a769054 | ||
|
|
7143f25dd1 | ||
|
|
5ca933d3ff | ||
|
|
9e73976342 | ||
|
|
e3c06858a1 | ||
|
|
d6a9cd82a9 | ||
|
|
5ea364c2e9 | ||
|
|
5f3eee4fa9 | ||
|
|
1011efbd8b | ||
|
|
182865de79 | ||
|
|
a9b31fcd4f | ||
|
|
cc66eeeb8e | ||
|
|
96cda7a0cb | ||
|
|
02f88265fa | ||
|
|
47c42732a7 | ||
|
|
c4c70508f6 | ||
|
|
216e93c9ba | ||
|
|
8358eaa1d9 | ||
|
|
7d70af072f | ||
|
|
e644bcb630 | ||
|
|
cbd98f723c | ||
|
|
4dfd5dfe1b | ||
|
|
9c6b6699cb | ||
|
|
29043ceaa9 | ||
|
|
345bc829c0 | ||
|
|
a30ae24192 | ||
|
|
d1da4df30d | ||
|
|
9c6a5bed32 | ||
|
|
be28150eeb | ||
|
|
c16e801fa5 | ||
|
|
16d3c78656 | ||
|
|
b4e509ea88 | ||
|
|
19304ffa8d | ||
|
|
ff96793208 | ||
|
|
30fbe4a8a3 | ||
|
|
70a3541280 | ||
|
|
30cd5a43cc | ||
|
|
8dc55a13df | ||
|
|
7b3211b6b5 | ||
|
|
69d8c519f2 | ||
|
|
77899799a3 | ||
|
|
3a666bf8a1 | ||
|
|
7493a5e0cf | ||
|
|
87283d927f | ||
|
|
88c74601a5 | ||
|
|
e5827b21c3 | ||
|
|
e4b17784a1 | ||
|
|
025b2de8aa | ||
|
|
cd666bea6e | ||
|
|
a899c9aeab | ||
|
|
0ce7612aa3 | ||
|
|
7a773dd690 | ||
|
|
34a258b680 | ||
|
|
72bab2382d | ||
|
|
20576a3b5f | ||
|
|
48c16d2aa5 | ||
|
|
f671447bff | ||
|
|
20dc83057b | ||
|
|
9ff9c92395 | ||
|
|
36de11e9a4 | ||
|
|
e2595fc67e | ||
|
|
4e3beeea16 | ||
|
|
dd74e5d361 | ||
|
|
9e8a07ea48 | ||
|
|
a2bd0702cb | ||
|
|
ad82733d2d | ||
|
|
aabc0ee26e | ||
|
|
cd4a92beee | ||
|
|
a8c820c486 | ||
|
|
c3b9b296eb | ||
|
|
508cf441d3 | ||
|
|
84c04b12fd | ||
|
|
d1c470f447 | ||
|
|
c4534c3525 | ||
|
|
2f41285420 | ||
|
|
a8ed22a0cf | ||
|
|
439e5acfd0 | ||
|
|
1df3ca46a1 | ||
|
|
15a54a9704 | ||
|
|
afc3af0030 | ||
|
|
33327afe2c | ||
|
|
c54229b748 | ||
|
|
3791eb5d3f | ||
|
|
502616179b | ||
|
|
191e7c5276 | ||
|
|
ee9f0d3d85 | ||
|
|
d41d4e379b | ||
|
|
b49e7a20cc | ||
|
|
4b1b24372a | ||
|
|
f0e292351a | ||
|
|
e72dfb7320 | ||
|
|
e42aab53cd | ||
|
|
f895223d70 | ||
|
|
93f86ba494 | ||
|
|
feede25916 | ||
|
|
29e64c7a70 | ||
|
|
fcc0ace7c0 | ||
|
|
1f97ee1928 | ||
|
|
f5f2c756b5 | ||
|
|
15745e7d1e | ||
|
|
889b5e16d4 | ||
|
|
211e614bd1 | ||
|
|
7212ed80ed | ||
|
|
01d691f5f6 | ||
|
|
bb24505f51 | ||
|
|
0257422324 | ||
|
|
0494e2b1df | ||
|
|
229d82eb2d | ||
|
|
940f27bbf3 | ||
|
|
b6b9e1f4da | ||
|
|
2f0426b4b5 | ||
|
|
5b7618ff6b | ||
|
|
77f42b77ee | ||
|
|
cdd6e68234 | ||
|
|
341028f68b | ||
|
|
836e276e40 | ||
|
|
9ec30b5cd1 | ||
|
|
46ecfe9ff4 | ||
|
|
aeaeac42c0 | ||
|
|
052a4b29f4 | ||
|
|
eb094630bc | ||
|
|
72c3b5173f | ||
|
|
7409b8bdaf | ||
|
|
b45f7ed360 | ||
|
|
4608318a57 | ||
|
|
0260e5c949 | ||
|
|
c826c2aea9 | ||
|
|
55e9a90632 | ||
|
|
db6b4e1405 | ||
|
|
2df09ec159 | ||
|
|
00cead832e | ||
|
|
99750ae231 | ||
|
|
d073aa25ba | ||
|
|
95777b6217 | ||
|
|
998b8f7265 | ||
|
|
0d6be5703e | ||
|
|
dc85e43445 | ||
|
|
55af258cce | ||
|
|
c84deb160b | ||
|
|
c50bb348d9 | ||
|
|
ae229c71dc | ||
|
|
f0d5a907ac | ||
|
|
b0a73e2a33 | ||
|
|
358c3d9baa | ||
|
|
2fd95d7128 | ||
|
|
afbe939af6 | ||
|
|
a398bc0185 | ||
|
|
d4a3e05d36 | ||
|
|
4b5c1f574b | ||
|
|
bdbe119934 | ||
|
|
50933cd23e | ||
|
|
45025a5027 | ||
|
|
5305726ece | ||
|
|
05a8ff9117 | ||
|
|
57c6cbe325 | ||
|
|
c5ba5ff4c8 | ||
|
|
95ada30c3f | ||
|
|
49b53da483 | ||
|
|
84c635c405 | ||
|
|
2be22e8578 | ||
|
|
74b52f068b | ||
|
|
98b3ac5221 | ||
|
|
5c7ffa6578 | ||
|
|
abfc3e2e79 | ||
|
|
2127a64497 | ||
|
|
8238bbcd4c | ||
|
|
0afe6c37bb | ||
|
|
ab95964027 | ||
|
|
15ff5a8489 | ||
|
|
0262d7e646 | ||
|
|
773ceb5f73 | ||
|
|
02a5148e02 | ||
|
|
86a7c75cc2 | ||
|
|
c57030a2ef | ||
|
|
6aebe7dd66 | ||
|
|
78265ab6a4 | ||
|
|
fe849d2ea0 | ||
|
|
d8ae52aeb0 | ||
|
|
ca5562225a | ||
|
|
9e65e2391a |
6
.github/actions/get-bootjdk/action.yml
vendored
6
.github/actions/get-bootjdk/action.yml
vendored
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -104,6 +104,6 @@ runs:
|
||||
- name: 'Export path to where BootJDK is installed'
|
||||
id: path-name
|
||||
run: |
|
||||
# Export the path
|
||||
echo 'path=bootjdk/jdk' >> $GITHUB_OUTPUT
|
||||
# Export the absolute path
|
||||
echo "path=`pwd`/bootjdk/jdk" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
|
||||
2
.github/actions/get-gtest/action.yml
vendored
2
.github/actions/get-gtest/action.yml
vendored
@@ -40,7 +40,7 @@ runs:
|
||||
var: GTEST_VERSION
|
||||
|
||||
- name: 'Checkout GTest source'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: google/googletest
|
||||
ref: 'release-${{ steps.version.outputs.value }}'
|
||||
|
||||
2
.github/actions/get-jtreg/action.yml
vendored
2
.github/actions/get-jtreg/action.yml
vendored
@@ -47,7 +47,7 @@ runs:
|
||||
key: jtreg-${{ steps.version.outputs.value }}
|
||||
|
||||
- name: 'Checkout the JTReg source'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: openjdk/jtreg
|
||||
ref: jtreg-${{ steps.version.outputs.value }}
|
||||
|
||||
7
.github/workflows/build-cross-compile.yml
vendored
7
.github/workflows/build-cross-compile.yml
vendored
@@ -85,7 +85,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 'Get the BootJDK'
|
||||
id: bootjdk
|
||||
@@ -100,6 +100,10 @@ jobs:
|
||||
with:
|
||||
platform: linux-x64
|
||||
|
||||
- name: 'Get GTest'
|
||||
id: gtest
|
||||
uses: ./.github/actions/get-gtest
|
||||
|
||||
# Upgrading apt to solve libc6 installation bugs, see JDK-8260460.
|
||||
- name: 'Install toolchain and dependencies'
|
||||
run: |
|
||||
@@ -155,6 +159,7 @@ jobs:
|
||||
--with-conf-name=linux-${{ matrix.target-cpu }}
|
||||
--with-version-opt=${GITHUB_ACTOR}-${GITHUB_SHA}
|
||||
--with-boot-jdk=${{ steps.bootjdk.outputs.path }}
|
||||
--with-gtest=${{ steps.gtest.outputs.path }}
|
||||
--with-zlib=system
|
||||
--enable-debug
|
||||
--disable-precompiled-headers
|
||||
|
||||
2
.github/workflows/build-linux.yml
vendored
2
.github/workflows/build-linux.yml
vendored
@@ -78,7 +78,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 'Get the BootJDK'
|
||||
id: bootjdk
|
||||
|
||||
2
.github/workflows/build-macos.yml
vendored
2
.github/workflows/build-macos.yml
vendored
@@ -68,7 +68,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 'Get the BootJDK'
|
||||
id: bootjdk
|
||||
|
||||
2
.github/workflows/build-windows.yml
vendored
2
.github/workflows/build-windows.yml
vendored
@@ -79,7 +79,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 'Get MSYS2'
|
||||
uses: ./.github/actions/get-msys2
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -105,7 +105,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout the JDK source'
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 'Get MSYS2'
|
||||
uses: ./.github/actions/get-msys2
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[general]
|
||||
project=jdk-updates
|
||||
jbs=JDK
|
||||
version=17.0.9
|
||||
version=17.0.10
|
||||
|
||||
[checks]
|
||||
error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists
|
||||
|
||||
12
README.md
12
README.md
@@ -9,11 +9,13 @@ It includes a number of enhancements in font rendering, ligatures, HiDPI support
|
||||
Download the latest releases of JetBrains Runtime to use with JetBrains IDEs. The full list
|
||||
can be found on the [releases page](https://github.com/JetBrains/JetBrainsRuntime/releases).
|
||||
|
||||
| IDE Version | Latest JBR | Date Released |
|
||||
| --- |--------------------------------------------------------------------------------------------------------|---------------|
|
||||
| 2023.1 | [17.0.6-b829.1](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.6b829.1) | 14-Feb-2023 |
|
||||
| 2022.3 | [17.0.5-b653.25](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.5b653.25) | 10-Jan-2023 |
|
||||
| 2022.2 | [17.0.5-b469.71](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.5b469.71) | 14-Nov-2022 |
|
||||
| IDE Version | Latest JBR | Date Released |
|
||||
|-------------|---------------------------------------------------------------------------------------------------------|---------------|
|
||||
| 2023.3 | [17.0.9b1087.7](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.9b1087.7) | 20-Nov-2023 |
|
||||
| 2023.2 | [17.0.9b1000.46](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.9b1000.46) | 01-Nov-2023 |
|
||||
| 2023.1 | [17.0.6-b829.1](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.6b829.1) | 14-Feb-2023 |
|
||||
| 2022.3 | [17.0.5-b653.25](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.5b653.25) | 10-Jan-2023 |
|
||||
| 2022.2 | [17.0.5-b469.71](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr-release-17.0.5b469.71) | 14-Nov-2022 |
|
||||
|
||||
|
||||
## Contents
|
||||
|
||||
@@ -88,6 +88,7 @@ $ make exploded-test TEST=tier2</code></pre>
|
||||
<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>
|
||||
|
||||
@@ -142,6 +142,11 @@ 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`.
|
||||
|
||||
@@ -77,13 +77,15 @@ function create_image_bundle {
|
||||
sed 's/JBR/JBRSDK/g' "$IMAGES_DIR"/"$__root_dir"/release > release
|
||||
mv release "$IMAGES_DIR"/"$__root_dir"/release
|
||||
cp $IMAGES_DIR/jdk/lib/src.zip "$IMAGES_DIR"/"$__root_dir"/lib
|
||||
cp $IMAGES_DIR/jdk/lib/server/*.jsa "$IMAGES_DIR"/"$__root_dir"/lib/server
|
||||
copy_jmods "$__modules" "$__modules_path" "$IMAGES_DIR"/"$__root_dir"/jmods
|
||||
"$IMAGES_DIR"/"$__root_dir"/bin/java -Xshare:dump
|
||||
"$IMAGES_DIR"/"$__root_dir"/bin/java -Xshare:dump -XX:-UseCompressedOops
|
||||
zip_native_debug_symbols $IMAGES_DIR/jdk "${JBR}_diz"
|
||||
fi
|
||||
|
||||
# jmod does not preserve file permissions (JDK-8173610)
|
||||
[ -f "$IMAGES_DIR"/"$__root_dir"/lib/jcef_helper ] && chmod a+x "$IMAGES_DIR"/"$__root_dir"/lib/jcef_helper
|
||||
[ -f "$IMAGES_DIR"/"$__root_dir"/lib/cef_server ] && chmod a+x "$IMAGES_DIR"/"$__root_dir"/lib/cef_server
|
||||
|
||||
echo Creating "$JBR".tar.gz ...
|
||||
|
||||
|
||||
@@ -77,13 +77,15 @@ function create_image_bundle {
|
||||
sed 's/JBR/JBRSDK/g' "$IMAGES_DIR"/"$__root_dir"/release > release
|
||||
mv release "$IMAGES_DIR"/"$__root_dir"/release
|
||||
cp $IMAGES_DIR/jdk/lib/src.zip "$IMAGES_DIR"/"$__root_dir"/lib
|
||||
cp $IMAGES_DIR/jdk/lib/server/*.jsa "$IMAGES_DIR"/"$__root_dir"/lib/server
|
||||
copy_jmods "$__modules" "$__modules_path" "$IMAGES_DIR"/"$__root_dir"/jmods
|
||||
"$IMAGES_DIR"/"$__root_dir"/bin/java -Xshare:dump
|
||||
"$IMAGES_DIR"/"$__root_dir"/bin/java -Xshare:dump -XX:-UseCompressedOops
|
||||
zip_native_debug_symbols $IMAGES_DIR/jdk "${JBR}_diz"
|
||||
fi
|
||||
|
||||
# jmod does not preserve file permissions (JDK-8173610)
|
||||
[ -f "$IMAGES_DIR"/"$__root_dir"/lib/jcef_helper ] && chmod a+x "$IMAGES_DIR"/"$__root_dir"/lib/jcef_helper
|
||||
[ -f "$IMAGES_DIR"/"$__root_dir"/lib/cef_server ] && chmod a+x "$IMAGES_DIR"/"$__root_dir"/lib/cef_server
|
||||
|
||||
echo Creating "$JBR".tar.gz ...
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ function create_image_bundle {
|
||||
sed 's/JBR/JBRSDK/g' "$IMAGES_DIR"/"$__root_dir"/release > release
|
||||
mv release "$IMAGES_DIR"/"$__root_dir"/release
|
||||
cp $IMAGES_DIR/jdk/lib/src.zip "$IMAGES_DIR"/"$__root_dir"/lib
|
||||
cp $IMAGES_DIR/jdk/lib/server/*.jsa "$IMAGES_DIR"/"$__root_dir"/lib/server
|
||||
copy_jmods "$__modules" "$__modules_path" "$IMAGES_DIR"/"$__root_dir"/jmods
|
||||
"$IMAGES_DIR"/"$__root_dir"/bin/java -Xshare:dump
|
||||
zip_native_debug_symbols $IMAGES_DIR/jdk "${JBR}_diz"
|
||||
fi
|
||||
|
||||
|
||||
@@ -80,8 +80,9 @@ function create_image_bundle {
|
||||
sed 's/JBR/JBRSDK/g' $JRE_CONTENTS/Home/release > release
|
||||
mv release $JRE_CONTENTS/Home/release
|
||||
cp $IMAGES_DIR/jdk-bundle/jdk-$JBSDK_VERSION.jdk/Contents/Home/lib/src.zip $JRE_CONTENTS/Home/lib
|
||||
cp $IMAGES_DIR/jdk-bundle/jdk-$JBSDK_VERSION.jdk/Contents/Home/lib/server/*.jsa $JRE_CONTENTS/Home/lib/server
|
||||
copy_jmods "$__modules" "$__modules_path" "$JRE_CONTENTS"/Home/jmods
|
||||
"$JRE_CONTENTS"/Home/bin/java -Xshare:dump
|
||||
"$JRE_CONTENTS"/Home/bin/java -Xshare:dump -XX:-UseCompressedOops
|
||||
zip_native_debug_symbols $IMAGES_DIR/jdk-bundle/jdk-$JBSDK_VERSION.jdk "${JBR}_diz"
|
||||
fi
|
||||
|
||||
@@ -96,7 +97,7 @@ function create_image_bundle {
|
||||
|
||||
echo Creating "$JBR".tar.gz ...
|
||||
# Normalize timestamp
|
||||
#find "$tmp"/"$__root_dir" -print0 | xargs -0 touch -c -h -t "$TOUCH_TIME"
|
||||
find "$tmp"/"$__root_dir" -print0 | xargs -0 touch -c -h -t "$TOUCH_TIME"
|
||||
|
||||
(cd "$tmp" &&
|
||||
find "$__root_dir" -print0 | LC_ALL=C sort -z | \
|
||||
|
||||
@@ -75,7 +75,6 @@ function create_image_bundle {
|
||||
sed 's/JBR/JBRSDK/g' $__root_dir/release > release
|
||||
mv release $__root_dir/release
|
||||
cp $IMAGES_DIR/jdk/lib/src.zip $__root_dir/lib
|
||||
cp $IMAGES_DIR/jdk/bin/server/*.jsa $__root_dir/bin/server
|
||||
for dir in $(ls -d $IMAGES_DIR/jdk/*); do
|
||||
rsync -amv --include="*/" --include="*.pdb" --exclude="*" $dir $__root_dir
|
||||
done
|
||||
|
||||
@@ -61,16 +61,17 @@ function create_image_bundle {
|
||||
--module-path $__modules_path --no-man-pages --compress=2 \
|
||||
--add-modules $__modules --output $__root_dir || do_exit $?
|
||||
|
||||
grep -v "^JAVA_VERSION" "$JSDK"/release | grep -v "^MODULES" >> $__root_dir/release
|
||||
if [ "$__arch_name" == "$JBRSDK_BUNDLE" ]; then
|
||||
grep -v "^JAVA_VERSION" "$JSDK"/release | grep -v "^MODULES" >> $__root_dir/release
|
||||
if [ "$__arch_name" == "$JBRSDK_BUNDLE" ]; then
|
||||
sed 's/JBR/JBRSDK/g' $__root_dir/release > release
|
||||
mv release $__root_dir/release
|
||||
cp $IMAGES_DIR/jdk/lib/src.zip $__root_dir/lib
|
||||
cp $IMAGES_DIR/jdk/bin/server/*.jsa $__root_dir/bin/server
|
||||
for dir in $(ls -d $IMAGES_DIR/jdk/*); do
|
||||
rsync -amv --include="*/" --include="*.pdb" --exclude="*" $dir $__root_dir
|
||||
done
|
||||
copy_jmods "$__modules" "$__modules_path" "$__root_dir"/jmods
|
||||
"$__root_dir"/bin/java -Xshare:dump
|
||||
"$__root_dir"/bin/java -Xshare:dump -XX:-UseCompressedOops
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -62,11 +62,11 @@ function create_image_bundle {
|
||||
sed 's/JBR/JBRSDK/g' $__root_dir/release > release
|
||||
mv release $__root_dir/release
|
||||
cp $IMAGES_DIR/jdk/lib/src.zip $__root_dir/lib
|
||||
cp $IMAGES_DIR/jdk/bin/server/*.jsa $__root_dir/bin/server
|
||||
for dir in $(ls -d $IMAGES_DIR/jdk/*); do
|
||||
rsync -amv --include="*/" --include="*.pdb" --exclude="*" $dir $__root_dir
|
||||
done
|
||||
copy_jmods "$__modules" "$__modules_path" "$__root_dir"/jmods
|
||||
"$__root_dir"/bin/java -Xshare:dump
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -523,7 +523,7 @@ define SetupRunGtestTestBody
|
||||
$$(subst $$(TOPDIR)/, , $$($1_TEST_RESULTS_DIR))))
|
||||
$$(if $$(wildcard $$($1_RESULT_FILE)), \
|
||||
$$(eval $1_TOTAL := $$(shell $$(AWK) '/==========.* tests? from .* \
|
||||
test cases? ran/ { print $$$$2 }' $$($1_RESULT_FILE))) \
|
||||
test (cases?|suites?) ran/ { print $$$$2 }' $$($1_RESULT_FILE))) \
|
||||
$$(if $$($1_TOTAL), , $$(eval $1_TOTAL := 0)) \
|
||||
$$(eval $1_PASSED := $$(shell $$(AWK) '/\[ PASSED \] .* tests?./ \
|
||||
{ print $$$$4 }' $$($1_RESULT_FILE))) \
|
||||
@@ -850,8 +850,9 @@ define SetupRunJtregTestBody
|
||||
endif
|
||||
endif
|
||||
|
||||
clean-workdir-$1:
|
||||
clean-outputdirs-$1:
|
||||
$$(RM) -r $$($1_TEST_SUPPORT_DIR)
|
||||
$$(RM) -r $$($1_TEST_RESULTS_DIR)
|
||||
|
||||
$1_COMMAND_LINE := \
|
||||
$$(JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \
|
||||
@@ -896,7 +897,7 @@ define SetupRunJtregTestBody
|
||||
done
|
||||
endif
|
||||
|
||||
run-test-$1: pre-run-test clean-workdir-$1
|
||||
run-test-$1: pre-run-test clean-outputdirs-$1
|
||||
$$(call LogWarn)
|
||||
$$(call LogWarn, Running test '$$($1_TEST)')
|
||||
$$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR) \
|
||||
@@ -933,9 +934,9 @@ define SetupRunJtregTestBody
|
||||
$$(eval $1_TOTAL := 1) \
|
||||
)
|
||||
|
||||
$1: run-test-$1 parse-test-$1 clean-workdir-$1
|
||||
$1: run-test-$1 parse-test-$1 clean-outputdirs-$1
|
||||
|
||||
TARGETS += $1 run-test-$1 parse-test-$1 clean-workdir-$1
|
||||
TARGETS += $1 run-test-$1 parse-test-$1 clean-outputdirs-$1
|
||||
TEST_TARGETS += parse-test-$1
|
||||
|
||||
endef
|
||||
|
||||
@@ -157,6 +157,10 @@ ifeq ($(UNAME_OS), CYGWIN)
|
||||
OPENJDK_TARGET_OS := windows
|
||||
OPENJDK_TARGET_OS_TYPE := windows
|
||||
OPENJDK_TARGET_OS_ENV := windows.cygwin
|
||||
else ifeq ($(UNAME_OS), MINGW64)
|
||||
OPENJDK_TARGET_OS := windows
|
||||
OPENJDK_TARGET_OS_TYPE := windows
|
||||
OPENJDK_TARGET_OS_ENV := windows.msys2
|
||||
else
|
||||
OPENJDK_TARGET_OS_TYPE:=unix
|
||||
ifeq ($(UNAME_OS), Linux)
|
||||
@@ -169,6 +173,9 @@ else
|
||||
OPENJDK_TARGET_OS_ENV := $(OPENJDK_TARGET_OS)
|
||||
endif
|
||||
|
||||
# Sanity check env detection
|
||||
$(info Detected target OS, type and env: [$(OPENJDK_TARGET_OS)] [$(OPENJDK_TARGET_OS_TYPE)] [$(OPENJDK_TARGET_OS_ENV)])
|
||||
|
||||
# Assume little endian unless otherwise specified
|
||||
OPENJDK_TARGET_CPU_ENDIAN := little
|
||||
|
||||
|
||||
@@ -358,9 +358,9 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
|
||||
# WARNING: This might be a bad thing to do. You need to be sure you want to
|
||||
# have a configuration in this directory. Do some sanity checks!
|
||||
|
||||
if test ! -e "$OUTPUTDIR/spec.gmk"; then
|
||||
# If we have a spec.gmk, we have run here before and we are OK. Otherwise, check for
|
||||
# other files
|
||||
if test ! -e "$OUTPUTDIR/spec.gmk" && test ! -e "$OUTPUTDIR/configure-support/generated-configure.sh"; then
|
||||
# If we have a spec.gmk or configure-support/generated-configure.sh,
|
||||
# we have run here before and we are OK. Otherwise, check for other files
|
||||
files_present=`$LS $OUTPUTDIR`
|
||||
# Configure has already touched config.log and confdefs.h in the current dir when this check
|
||||
# is performed.
|
||||
@@ -375,8 +375,9 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
|
||||
AC_MSG_NOTICE([Current directory is $CONFIGURE_START_DIR.])
|
||||
AC_MSG_NOTICE([Since this is not the source root, configure will output the configuration here])
|
||||
AC_MSG_NOTICE([(as opposed to creating a configuration in <src_root>/build/<conf-name>).])
|
||||
AC_MSG_NOTICE([However, this directory is not empty. This is not allowed, since it could])
|
||||
AC_MSG_NOTICE([seriously mess up just about everything.])
|
||||
AC_MSG_NOTICE([However, this directory is not empty, additionally to some allowed files])
|
||||
AC_MSG_NOTICE([it contains $filtered_files.])
|
||||
AC_MSG_NOTICE([This is not allowed, since it could seriously mess up just about everything.])
|
||||
AC_MSG_NOTICE([Try 'cd $TOPDIR' and restart configure])
|
||||
AC_MSG_NOTICE([(or create a new empty directory and cd to it).])
|
||||
AC_MSG_ERROR([Will not continue creating configuration in $CONFIGURE_START_DIR])
|
||||
|
||||
@@ -191,18 +191,15 @@ TOOLCHAIN_POST_DETECTION
|
||||
TOOLCHAIN_SETUP_BUILD_COMPILERS
|
||||
TOOLCHAIN_MISC_CHECKS
|
||||
|
||||
# Setup the JTReg Regression Test Harness.
|
||||
TOOLCHAIN_SETUP_JTREG
|
||||
|
||||
# Setup the Java Microbenchmark Harness (JMH)
|
||||
LIB_TESTS_SETUP_JMH
|
||||
|
||||
# Setup Jib dependency tool
|
||||
TOOLCHAIN_SETUP_JIB
|
||||
|
||||
# After toolchain setup, we need to process some flags to be able to continue.
|
||||
FLAGS_POST_TOOLCHAIN
|
||||
|
||||
# Setup the tools needed to test the JDK (JTReg Regression Test Harness,
|
||||
# Java Microbenchmark Harness (JMH) and the Jib dependency tool).
|
||||
LIB_TESTS_SETUP_JTREG
|
||||
LIB_TESTS_SETUP_JMH
|
||||
LIB_TESTS_SETUP_JIB
|
||||
|
||||
# Now we can test some aspects on the target using configure macros.
|
||||
PLATFORM_SETUP_OPENJDK_TARGET_BITS
|
||||
PLATFORM_SETUP_OPENJDK_TARGET_ENDIANNESS
|
||||
@@ -247,7 +244,8 @@ HOTSPOT_SETUP_MISC
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
JDKOPT_ENABLE_DISABLE_FAILURE_HANDLER
|
||||
LIB_TESTS_ENABLE_DISABLE_FAILURE_HANDLER
|
||||
|
||||
JDKOPT_ENABLE_DISABLE_GENERATE_CLASSLIST
|
||||
JDKOPT_EXCLUDE_TRANSLATIONS
|
||||
JDKOPT_ENABLE_DISABLE_MANPAGES
|
||||
|
||||
@@ -564,29 +564,6 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JLINK_OPTIONS],
|
||||
AC_SUBST(JLINK_KEEP_PACKAGED_MODULES)
|
||||
])
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Check if building of the jtreg failure handler should be enabled.
|
||||
#
|
||||
AC_DEFUN_ONCE([JDKOPT_ENABLE_DISABLE_FAILURE_HANDLER],
|
||||
[
|
||||
UTIL_ARG_ENABLE(NAME: jtreg-failure-handler, DEFAULT: auto,
|
||||
RESULT: BUILD_FAILURE_HANDLER,
|
||||
DESC: [enable building of the jtreg failure handler],
|
||||
DEFAULT_DESC: [enabled if jtreg is present],
|
||||
CHECKING_MSG: [if the jtreg failure handler should be built],
|
||||
CHECK_AVAILABLE: [
|
||||
AC_MSG_CHECKING([if the jtreg failure handler is available])
|
||||
if test "x$JT_HOME" != "x"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AVAILABLE=false
|
||||
AC_MSG_RESULT([no (jtreg not present)])
|
||||
fi
|
||||
])
|
||||
AC_SUBST(BUILD_FAILURE_HANDLER)
|
||||
])
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Enable or disable generation of the classlist at build time
|
||||
@@ -812,6 +789,9 @@ AC_DEFUN([JDKOPT_CHECK_CODESIGN_PARAMS],
|
||||
$RM "$CODESIGN_TESTFILE"
|
||||
$TOUCH "$CODESIGN_TESTFILE"
|
||||
CODESIGN_SUCCESS=false
|
||||
|
||||
$ECHO "check codesign, calling $CODESIGN $PARAMS $CODESIGN_TESTFILE" >&AS_MESSAGE_LOG_FD
|
||||
|
||||
eval \"$CODESIGN\" $PARAMS \"$CODESIGN_TESTFILE\" 2>&AS_MESSAGE_LOG_FD \
|
||||
>&AS_MESSAGE_LOG_FD && CODESIGN_SUCCESS=true
|
||||
$RM "$CODESIGN_TESTFILE"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2018, 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
|
||||
@@ -23,6 +23,13 @@
|
||||
# questions.
|
||||
#
|
||||
|
||||
################################################################################
|
||||
# Setup libraries and functionalities needed to test the JDK.
|
||||
################################################################################
|
||||
|
||||
# Minimum supported version
|
||||
JTREG_MINIMUM_VERSION=7.3.1
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Setup and check for gtest framework source files
|
||||
@@ -47,9 +54,25 @@ AC_DEFUN_ONCE([LIB_TESTS_SETUP_GTEST],
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Can't find 'googlemock/include/gmock/gmock.h' under ${with_gtest} given with the --with-gtest option.])
|
||||
else
|
||||
GTEST_FRAMEWORK_SRC=${with_gtest}
|
||||
GTEST_FRAMEWORK_SRC=$with_gtest
|
||||
AC_MSG_RESULT([$GTEST_FRAMEWORK_SRC])
|
||||
UTIL_FIXUP_PATH([GTEST_FRAMEWORK_SRC])
|
||||
|
||||
# Try to verify version. We require 1.8.1, but this can not be directly
|
||||
# determined. :-( Instead, there are different, incorrect version
|
||||
# numbers we can look for.
|
||||
GTEST_VERSION_1="`$GREP GOOGLETEST_VERSION $GTEST_FRAMEWORK_SRC/CMakeLists.txt | $SED -E -e 's/set\(GOOGLETEST_VERSION (.*)\)/\1/'`"
|
||||
if test "x$GTEST_VERSION_1" != "x1.9.0"; then
|
||||
AC_MSG_ERROR([gtest at $GTEST_FRAMEWORK_SRC does not seem to be version 1.8.1])
|
||||
fi
|
||||
|
||||
# We cannot grep for "AC_IN*T" as a literal since then m4 will treat it as a macro
|
||||
# and expand it.
|
||||
# Additional [] needed to keep m4 from mangling shell constructs.
|
||||
[ GTEST_VERSION_2="`$GREP -A1 ^.C_INIT $GTEST_FRAMEWORK_SRC/configure.ac | $TAIL -n 1 | $SED -E -e 's/ +\[(.*)],/\1/'`" ]
|
||||
if test "x$GTEST_VERSION_2" != "x1.8.0"; then
|
||||
AC_MSG_ERROR([gtest at $GTEST_FRAMEWORK_SRC does not seem to be version 1.8.1 B])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -118,3 +141,163 @@ AC_DEFUN_ONCE([LIB_TESTS_SETUP_JMH],
|
||||
AC_SUBST(JMH_COMMONS_MATH_JAR)
|
||||
AC_SUBST(JMH_VERSION)
|
||||
])
|
||||
|
||||
# Setup the JTReg Regression Test Harness.
|
||||
AC_DEFUN_ONCE([LIB_TESTS_SETUP_JTREG],
|
||||
[
|
||||
AC_ARG_WITH(jtreg, [AS_HELP_STRING([--with-jtreg],
|
||||
[Regression Test Harness @<:@probed@:>@])])
|
||||
|
||||
if test "x$with_jtreg" = xno; then
|
||||
# jtreg disabled
|
||||
AC_MSG_CHECKING([for jtreg test harness])
|
||||
AC_MSG_RESULT([no, disabled])
|
||||
elif test "x$with_jtreg" != xyes && test "x$with_jtreg" != x; then
|
||||
if test -d "$with_jtreg"; then
|
||||
# An explicit path is specified, use it.
|
||||
JT_HOME="$with_jtreg"
|
||||
else
|
||||
case "$with_jtreg" in
|
||||
*.zip )
|
||||
JTREG_SUPPORT_DIR=$CONFIGURESUPPORT_OUTPUTDIR/jtreg
|
||||
$RM -rf $JTREG_SUPPORT_DIR
|
||||
$MKDIR -p $JTREG_SUPPORT_DIR
|
||||
$UNZIP -qq -d $JTREG_SUPPORT_DIR $with_jtreg
|
||||
|
||||
# Try to find jtreg to determine JT_HOME path
|
||||
JTREG_PATH=`$FIND $JTREG_SUPPORT_DIR | $GREP "/bin/jtreg"`
|
||||
if test "x$JTREG_PATH" != x; then
|
||||
JT_HOME=$($DIRNAME $($DIRNAME $JTREG_PATH))
|
||||
fi
|
||||
;;
|
||||
* )
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
UTIL_FIXUP_PATH([JT_HOME])
|
||||
if test ! -d "$JT_HOME"; then
|
||||
AC_MSG_ERROR([jtreg home directory from --with-jtreg=$with_jtreg does not exist])
|
||||
fi
|
||||
|
||||
if test ! -e "$JT_HOME/lib/jtreg.jar"; then
|
||||
AC_MSG_ERROR([jtreg home directory from --with-jtreg=$with_jtreg is not a valid jtreg home])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for jtreg test harness])
|
||||
AC_MSG_RESULT([$JT_HOME])
|
||||
else
|
||||
# Try to locate jtreg using the JT_HOME environment variable
|
||||
if test "x$JT_HOME" != x; then
|
||||
# JT_HOME set in environment, use it
|
||||
if test ! -d "$JT_HOME"; then
|
||||
AC_MSG_WARN([Ignoring JT_HOME pointing to invalid directory: $JT_HOME])
|
||||
JT_HOME=
|
||||
else
|
||||
if test ! -e "$JT_HOME/lib/jtreg.jar"; then
|
||||
AC_MSG_WARN([Ignoring JT_HOME which is not a valid jtreg home: $JT_HOME])
|
||||
JT_HOME=
|
||||
else
|
||||
AC_MSG_NOTICE([Located jtreg using JT_HOME from environment])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$JT_HOME" = x; then
|
||||
# JT_HOME is not set in environment, or was deemed invalid.
|
||||
# Try to find jtreg on path
|
||||
UTIL_LOOKUP_PROGS(JTREGEXE, jtreg)
|
||||
if test "x$JTREGEXE" != x; then
|
||||
# That's good, now try to derive JT_HOME
|
||||
JT_HOME=`(cd $($DIRNAME $JTREGEXE)/.. && pwd)`
|
||||
if test ! -e "$JT_HOME/lib/jtreg.jar"; then
|
||||
AC_MSG_WARN([Ignoring jtreg from path since a valid jtreg home cannot be found])
|
||||
JT_HOME=
|
||||
else
|
||||
AC_MSG_NOTICE([Located jtreg using jtreg executable in path])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for jtreg test harness])
|
||||
if test "x$JT_HOME" != x; then
|
||||
AC_MSG_RESULT([$JT_HOME])
|
||||
else
|
||||
AC_MSG_RESULT([no, not found])
|
||||
|
||||
if test "x$with_jtreg" = xyes; then
|
||||
AC_MSG_ERROR([--with-jtreg was specified, but no jtreg found.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
UTIL_FIXUP_PATH(JT_HOME)
|
||||
AC_SUBST(JT_HOME)
|
||||
|
||||
# Verify jtreg version
|
||||
if test "x$JT_HOME" != x; then
|
||||
AC_MSG_CHECKING([jtreg version number])
|
||||
# jtreg -version looks like this: "jtreg 6.1+1-19"
|
||||
# Extract actual version part ("6.1" in this case)
|
||||
jtreg_version_full=`$JAVA -jar $JT_HOME/lib/jtreg.jar -version | $HEAD -n 1 | $CUT -d ' ' -f 2`
|
||||
jtreg_version=${jtreg_version_full/%+*}
|
||||
AC_MSG_RESULT([$jtreg_version])
|
||||
|
||||
# This is a simplified version of TOOLCHAIN_CHECK_COMPILER_VERSION
|
||||
comparable_actual_version=`$AWK -F. '{ printf("%05d%05d%05d%05d\n", [$]1, [$]2, [$]3, [$]4) }' <<< "$jtreg_version"`
|
||||
comparable_minimum_version=`$AWK -F. '{ printf("%05d%05d%05d%05d\n", [$]1, [$]2, [$]3, [$]4) }' <<< "$JTREG_MINIMUM_VERSION"`
|
||||
if test $comparable_actual_version -lt $comparable_minimum_version ; then
|
||||
AC_MSG_ERROR([jtreg version is too old, at least version $JTREG_MINIMUM_VERSION is required])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
# Setup the JIB dependency resolver
|
||||
AC_DEFUN_ONCE([LIB_TESTS_SETUP_JIB],
|
||||
[
|
||||
AC_ARG_WITH(jib, [AS_HELP_STRING([--with-jib],
|
||||
[Jib dependency management tool @<:@not used@:>@])])
|
||||
|
||||
if test "x$with_jib" = xno || test "x$with_jib" = x; then
|
||||
# jib disabled
|
||||
AC_MSG_CHECKING([for jib])
|
||||
AC_MSG_RESULT(no)
|
||||
elif test "x$with_jib" = xyes; then
|
||||
AC_MSG_ERROR([Must supply a value to --with-jib])
|
||||
else
|
||||
JIB_HOME="${with_jib}"
|
||||
AC_MSG_CHECKING([for jib])
|
||||
AC_MSG_RESULT(${JIB_HOME})
|
||||
if test ! -d "${JIB_HOME}"; then
|
||||
AC_MSG_ERROR([--with-jib must be a directory])
|
||||
fi
|
||||
JIB_JAR=$(ls ${JIB_HOME}/lib/jib-*.jar)
|
||||
if test ! -f "${JIB_JAR}"; then
|
||||
AC_MSG_ERROR([Could not find jib jar file in ${JIB_HOME}])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(JIB_HOME)
|
||||
])
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Check if building of the jtreg failure handler should be enabled.
|
||||
#
|
||||
AC_DEFUN_ONCE([LIB_TESTS_ENABLE_DISABLE_FAILURE_HANDLER],
|
||||
[
|
||||
UTIL_ARG_ENABLE(NAME: jtreg-failure-handler, DEFAULT: auto,
|
||||
RESULT: BUILD_FAILURE_HANDLER,
|
||||
DESC: [enable building of the jtreg failure handler],
|
||||
DEFAULT_DESC: [enabled if jtreg is present],
|
||||
CHECKING_MSG: [if the jtreg failure handler should be built],
|
||||
CHECK_AVAILABLE: [
|
||||
AC_MSG_CHECKING([if the jtreg failure handler is available])
|
||||
if test "x$JT_HOME" != "x"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AVAILABLE=false
|
||||
AC_MSG_RESULT([no (jtreg not present)])
|
||||
fi
|
||||
])
|
||||
AC_SUBST(BUILD_FAILURE_HANDLER)
|
||||
])
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -35,6 +35,7 @@ AC_DEFUN_ONCE([LIB_SETUP_X11],
|
||||
X_CFLAGS=
|
||||
X_LIBS=
|
||||
else
|
||||
x_libraries_orig="$x_libraries"
|
||||
|
||||
if test "x${with_x}" = xno; then
|
||||
AC_MSG_ERROR([It is not possible to disable the use of X11. Remove the --without-x option.])
|
||||
@@ -48,6 +49,7 @@ AC_DEFUN_ONCE([LIB_SETUP_X11],
|
||||
fi
|
||||
if test "x$x_libraries" = xNONE; then
|
||||
x_libraries="${with_x}/lib"
|
||||
x_libraries_orig="$x_libraries"
|
||||
fi
|
||||
else
|
||||
# Check if the user has specified sysroot, but not --with-x, --x-includes or --x-libraries.
|
||||
@@ -82,8 +84,8 @@ AC_DEFUN_ONCE([LIB_SETUP_X11],
|
||||
AC_PATH_XTRA
|
||||
|
||||
# AC_PATH_XTRA creates X_LIBS and sometimes adds -R flags. When cross compiling
|
||||
# this doesn't make sense so we remove it.
|
||||
if test "x$COMPILE_TYPE" = xcross; then
|
||||
# this doesn't make sense so we remove it; same for sysroot (devkit).
|
||||
if test "x$COMPILE_TYPE" = xcross || (test "x$SYSROOT" != "x" && test "x$x_libraries_orig" = xNONE); then
|
||||
X_LIBS=`$ECHO $X_LIBS | $SED 's/-R \{0,1\}[[^ ]]*//g'`
|
||||
fi
|
||||
|
||||
|
||||
@@ -160,12 +160,6 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES],
|
||||
fi
|
||||
fi
|
||||
|
||||
# Because RISC-V only has word-sized atomics, it requries libatomic where
|
||||
# other common architectures do not. So link libatomic by default.
|
||||
if test "x$OPENJDK_TARGET_OS" = xlinux && test "x$OPENJDK_TARGET_CPU" = xriscv64; then
|
||||
BASIC_JVM_LIBS="$BASIC_JVM_LIBS -latomic"
|
||||
fi
|
||||
|
||||
# perfstat lib
|
||||
if test "x$OPENJDK_TARGET_OS" = xaix; then
|
||||
BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lperfstat"
|
||||
|
||||
@@ -573,6 +573,8 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
|
||||
HOTSPOT_$1_CPU_DEFINE=S390
|
||||
elif test "x$OPENJDK_$1_CPU" = xs390x; then
|
||||
HOTSPOT_$1_CPU_DEFINE=S390
|
||||
elif test "x$OPENJDK_$1_CPU" = xloongarch64; then
|
||||
HOTSPOT_$1_CPU_DEFINE=LOONGARCH64
|
||||
elif test "x$OPENJDK_$1_CPU" != x; then
|
||||
HOTSPOT_$1_CPU_DEFINE=$(echo $OPENJDK_$1_CPU | tr a-z A-Z)
|
||||
fi
|
||||
|
||||
@@ -58,9 +58,6 @@ TOOLCHAIN_MINIMUM_VERSION_xlc=""
|
||||
# Minimum supported linker versions, empty means unspecified
|
||||
TOOLCHAIN_MINIMUM_LD_VERSION_gcc="2.18"
|
||||
|
||||
# Minimum supported version
|
||||
JTREG_MINIMUM_VERSION=6.1
|
||||
|
||||
# Prepare the system so that TOOLCHAIN_CHECK_COMPILER_VERSION can be called.
|
||||
# Must have CC_VERSION_NUMBER and CXX_VERSION_NUMBER.
|
||||
# $1 - optional variable prefix for compiler and version variables (BUILD_)
|
||||
@@ -994,140 +991,3 @@ AC_DEFUN_ONCE([TOOLCHAIN_MISC_CHECKS],
|
||||
fi
|
||||
AC_SUBST(HOTSPOT_TOOLCHAIN_TYPE)
|
||||
])
|
||||
|
||||
# Setup the JTReg Regression Test Harness.
|
||||
AC_DEFUN_ONCE([TOOLCHAIN_SETUP_JTREG],
|
||||
[
|
||||
AC_ARG_WITH(jtreg, [AS_HELP_STRING([--with-jtreg],
|
||||
[Regression Test Harness @<:@probed@:>@])])
|
||||
|
||||
if test "x$with_jtreg" = xno; then
|
||||
# jtreg disabled
|
||||
AC_MSG_CHECKING([for jtreg test harness])
|
||||
AC_MSG_RESULT([no, disabled])
|
||||
elif test "x$with_jtreg" != xyes && test "x$with_jtreg" != x; then
|
||||
if test -d "$with_jtreg"; then
|
||||
# An explicit path is specified, use it.
|
||||
JT_HOME="$with_jtreg"
|
||||
else
|
||||
case "$with_jtreg" in
|
||||
*.zip )
|
||||
JTREG_SUPPORT_DIR=$CONFIGURESUPPORT_OUTPUTDIR/jtreg
|
||||
$RM -rf $JTREG_SUPPORT_DIR
|
||||
$MKDIR -p $JTREG_SUPPORT_DIR
|
||||
$UNZIP -qq -d $JTREG_SUPPORT_DIR $with_jtreg
|
||||
|
||||
# Try to find jtreg to determine JT_HOME path
|
||||
JTREG_PATH=`$FIND $JTREG_SUPPORT_DIR | $GREP "/bin/jtreg"`
|
||||
if test "x$JTREG_PATH" != x; then
|
||||
JT_HOME=$($DIRNAME $($DIRNAME $JTREG_PATH))
|
||||
fi
|
||||
;;
|
||||
* )
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
UTIL_FIXUP_PATH([JT_HOME])
|
||||
if test ! -d "$JT_HOME"; then
|
||||
AC_MSG_ERROR([jtreg home directory from --with-jtreg=$with_jtreg does not exist])
|
||||
fi
|
||||
|
||||
if test ! -e "$JT_HOME/lib/jtreg.jar"; then
|
||||
AC_MSG_ERROR([jtreg home directory from --with-jtreg=$with_jtreg is not a valid jtreg home])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for jtreg test harness])
|
||||
AC_MSG_RESULT([$JT_HOME])
|
||||
else
|
||||
# Try to locate jtreg using the JT_HOME environment variable
|
||||
if test "x$JT_HOME" != x; then
|
||||
# JT_HOME set in environment, use it
|
||||
if test ! -d "$JT_HOME"; then
|
||||
AC_MSG_WARN([Ignoring JT_HOME pointing to invalid directory: $JT_HOME])
|
||||
JT_HOME=
|
||||
else
|
||||
if test ! -e "$JT_HOME/lib/jtreg.jar"; then
|
||||
AC_MSG_WARN([Ignoring JT_HOME which is not a valid jtreg home: $JT_HOME])
|
||||
JT_HOME=
|
||||
else
|
||||
AC_MSG_NOTICE([Located jtreg using JT_HOME from environment])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$JT_HOME" = x; then
|
||||
# JT_HOME is not set in environment, or was deemed invalid.
|
||||
# Try to find jtreg on path
|
||||
UTIL_LOOKUP_PROGS(JTREGEXE, jtreg)
|
||||
if test "x$JTREGEXE" != x; then
|
||||
# That's good, now try to derive JT_HOME
|
||||
JT_HOME=`(cd $($DIRNAME $JTREGEXE)/.. && pwd)`
|
||||
if test ! -e "$JT_HOME/lib/jtreg.jar"; then
|
||||
AC_MSG_WARN([Ignoring jtreg from path since a valid jtreg home cannot be found])
|
||||
JT_HOME=
|
||||
else
|
||||
AC_MSG_NOTICE([Located jtreg using jtreg executable in path])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for jtreg test harness])
|
||||
if test "x$JT_HOME" != x; then
|
||||
AC_MSG_RESULT([$JT_HOME])
|
||||
else
|
||||
AC_MSG_RESULT([no, not found])
|
||||
|
||||
if test "x$with_jtreg" = xyes; then
|
||||
AC_MSG_ERROR([--with-jtreg was specified, but no jtreg found.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
UTIL_FIXUP_PATH(JT_HOME)
|
||||
AC_SUBST(JT_HOME)
|
||||
|
||||
# Verify jtreg version
|
||||
if test "x$JT_HOME" != x; then
|
||||
AC_MSG_CHECKING([jtreg version number])
|
||||
# jtreg -version looks like this: "jtreg 6.1+1-19"
|
||||
# Extract actual version part ("6.1" in this case)
|
||||
jtreg_version_full=`$JAVA -jar $JT_HOME/lib/jtreg.jar -version | $HEAD -n 1 | $CUT -d ' ' -f 2`
|
||||
jtreg_version=${jtreg_version_full/%+*}
|
||||
AC_MSG_RESULT([$jtreg_version])
|
||||
|
||||
# This is a simplified version of TOOLCHAIN_CHECK_COMPILER_VERSION
|
||||
comparable_actual_version=`$AWK -F. '{ printf("%05d%05d%05d%05d\n", [$]1, [$]2, [$]3, [$]4) }' <<< "$jtreg_version"`
|
||||
comparable_minimum_version=`$AWK -F. '{ printf("%05d%05d%05d%05d\n", [$]1, [$]2, [$]3, [$]4) }' <<< "$JTREG_MINIMUM_VERSION"`
|
||||
if test $comparable_actual_version -lt $comparable_minimum_version ; then
|
||||
AC_MSG_ERROR([jtreg version is too old, at least version $JTREG_MINIMUM_VERSION is required])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
# Setup the JIB dependency resolver
|
||||
AC_DEFUN_ONCE([TOOLCHAIN_SETUP_JIB],
|
||||
[
|
||||
AC_ARG_WITH(jib, [AS_HELP_STRING([--with-jib],
|
||||
[Jib dependency management tool @<:@not used@:>@])])
|
||||
|
||||
if test "x$with_jib" = xno || test "x$with_jib" = x; then
|
||||
# jib disabled
|
||||
AC_MSG_CHECKING([for jib])
|
||||
AC_MSG_RESULT(no)
|
||||
elif test "x$with_jib" = xyes; then
|
||||
AC_MSG_ERROR([Must supply a value to --with-jib])
|
||||
else
|
||||
JIB_HOME="${with_jib}"
|
||||
AC_MSG_CHECKING([for jib])
|
||||
AC_MSG_RESULT(${JIB_HOME})
|
||||
if test ! -d "${JIB_HOME}"; then
|
||||
AC_MSG_ERROR([--with-jib must be a directory])
|
||||
fi
|
||||
JIB_JAR=$(ls ${JIB_HOME}/lib/jib-*.jar)
|
||||
if test ! -f "${JIB_JAR}"; then
|
||||
AC_MSG_ERROR([Could not find jib jar file in ${JIB_HOME}])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(JIB_HOME)
|
||||
])
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
# Versions and download locations for dependencies used by GitHub Actions (GHA)
|
||||
|
||||
GTEST_VERSION=1.8.1
|
||||
JTREG_VERSION=6.1+3
|
||||
JTREG_VERSION=7.3.1+1
|
||||
|
||||
LINUX_X64_BOOT_JDK_EXT=tar.gz
|
||||
LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.6%2B10/OpenJDK17U-jdk_x64_linux_hotspot_17.0.6_10.tar.gz
|
||||
|
||||
@@ -917,10 +917,7 @@ var getJibProfilesProfiles = function (input, common, data) {
|
||||
target_os: input.build_os,
|
||||
target_cpu: input.build_cpu,
|
||||
dependencies: [ "jtreg", "gnumake", "boot_jdk", "devkit", "jib" ],
|
||||
labels: "test",
|
||||
environment: {
|
||||
"JT_JAVA": common.boot_jdk_home
|
||||
}
|
||||
labels: "test"
|
||||
}
|
||||
};
|
||||
profiles = concatObjects(profiles, testOnlyProfiles);
|
||||
@@ -1156,9 +1153,9 @@ var getJibProfilesDependencies = function (input, common) {
|
||||
jtreg: {
|
||||
server: "jpg",
|
||||
product: "jtreg",
|
||||
version: "6",
|
||||
version: "7.3.1",
|
||||
build_number: "1",
|
||||
file: "bundles/jtreg-6+1.zip",
|
||||
file: "bundles/jtreg-7.3.1+1.zip",
|
||||
environment_name: "JT_HOME",
|
||||
environment_path: input.get("jtreg", "home_path") + "/bin",
|
||||
configure_args: "--with-jtreg=" + input.get("jtreg", "home_path"),
|
||||
|
||||
@@ -28,12 +28,12 @@
|
||||
|
||||
DEFAULT_VERSION_FEATURE=17
|
||||
DEFAULT_VERSION_INTERIM=0
|
||||
DEFAULT_VERSION_UPDATE=9
|
||||
DEFAULT_VERSION_UPDATE=10
|
||||
DEFAULT_VERSION_PATCH=0
|
||||
DEFAULT_VERSION_EXTRA1=0
|
||||
DEFAULT_VERSION_EXTRA2=0
|
||||
DEFAULT_VERSION_EXTRA3=0
|
||||
DEFAULT_VERSION_DATE=2023-10-17
|
||||
DEFAULT_VERSION_DATE=2024-01-16
|
||||
DEFAULT_VERSION_CLASSFILE_MAJOR=61 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
||||
DEFAULT_VERSION_CLASSFILE_MINOR=0
|
||||
DEFAULT_VERSION_DOCS_API_SINCE=11
|
||||
|
||||
21
make/data/cacerts/digicertcseccrootg5
Normal file
21
make/data/cacerts/digicertcseccrootg5
Normal file
@@ -0,0 +1,21 @@
|
||||
Owner: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US
|
||||
Issuer: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US
|
||||
Serial number: 3698fe712d519f3ced0fdb7b1643011
|
||||
Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046
|
||||
Signature algorithm name: SHA384withECDSA
|
||||
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICFjCCAZ2gAwIBAgIQA2mP5xLVGfPO0P23sWQwETAKBggqhkjOPQQDAzBNMQsw
|
||||
CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERp
|
||||
Z2lDZXJ0IENTIEVDQyBQMzg0IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYw
|
||||
MTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu
|
||||
Yy4xJTAjBgNVBAMTHERpZ2lDZXJ0IENTIEVDQyBQMzg0IFJvb3QgRzUwdjAQBgcq
|
||||
hkjOPQIBBgUrgQQAIgNiAAR/FK2Ftpf9AiE1TWDoOJOTmz0FEG2v0/7v+rv7c5nz
|
||||
7DISjcdouIveiaKIVHeNuyF+M5VWlgno1YyhBLibbhkAYuhCKKZYN4QZVSZ7Mzdn
|
||||
8ppyraGurgBCPBx+uHqeIZyjQjBAMB0GA1UdDgQWBBTwjJhxOThlwjobphdmHcjt
|
||||
Zd6SNjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQD
|
||||
AwNnADBkAjAjb+EAGSZQ5EYgZYs3p8/rBuHMMskqoewyDXOiHgIcNWEqTmmrOXft
|
||||
l4jAfWvqid0CMEPx0VijdT6Gm7ZVEYsX9z3+CmnFf07GdRtalMvqERHGCCKI3tB6
|
||||
oqV56OMhp80Tsw==
|
||||
-----END CERTIFICATE-----
|
||||
38
make/data/cacerts/digicertcsrsarootg5
Normal file
38
make/data/cacerts/digicertcsrsarootg5
Normal file
@@ -0,0 +1,38 @@
|
||||
Owner: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US
|
||||
Issuer: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US
|
||||
Serial number: 6cee131be6d55c807f7c0c7fb44e620
|
||||
Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046
|
||||
Signature algorithm name: SHA384withRSA
|
||||
Subject Public Key Algorithm: 4096-bit RSA key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFZDCCA0ygAwIBAgIQBs7hMb5tVcgH98DH+0TmIDANBgkqhkiG9w0BAQwFADBM
|
||||
MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJDAiBgNVBAMT
|
||||
G0RpZ2lDZXJ0IENTIFJTQTQwOTYgUm9vdCBHNTAeFw0yMTAxMTUwMDAwMDBaFw00
|
||||
NjAxMTQyMzU5NTlaMEwxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg
|
||||
SW5jLjEkMCIGA1UEAxMbRGlnaUNlcnQgQ1MgUlNBNDA5NiBSb290IEc1MIICIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtjNzgNhiA3AULBEcOV58rnyDhh3+
|
||||
Ji9MJK2L6oNfqbw9W/wLmEwCRzDs4v7s6DRbZl6/O9cspiX/jFmz3+rafCnZRlBy
|
||||
CB1u0RsK3R/NmYn6Dw9zxOGcHXUyzW+X2ipqlbJsyQnQ6gt7fRcGSZnv1t7gyFPU
|
||||
rsZ38Ya7Ixy4wN9Z94590e+C5iaLWji1/3XVstlPCfM3iFDaEaSKFBTRUwQAffNq
|
||||
RBj+UHAyBxyomg46HcUKH24LJmm3PKJXcCyG+kxulalYQ7msEtb/P+3XQxdrTM6e
|
||||
xJCr//oQUJqjkFfW54wQrp8WGs81HX/Xdu2KnDWnKLinXSH8MDfd3ggZTxXG56ba
|
||||
kEeO95RTTI5TAr79meXqhtCvAwLTm6qT8asojiAB/0z7zLcpQPWHpBITBR9DbtdR
|
||||
UJ84tCDtFwkSj8y5Ga+fzb5pEdOvVRBtF4Z5llLGsgCd5a84sDX0iGuPDgQ9fO6v
|
||||
zdNqEErGzYbKIj2hSlz7Dv+I31xip8C5HtmsbH44N/53kyXChYpPtTcGWgaBFPHO
|
||||
lJ2ZkeoyWs5nPW4EZq0MTy2jLvee9Xid9wr9fo/jQopVlrzxnzct/J5flf6MGBv8
|
||||
jv1LkK/XA2gSY6zik6eiywTlT2TOA/rGFJ/Zi+jM1GKMa+QALBmfGgbGMYFU+1Mk
|
||||
mq9Vmbqdda64wt0CAwEAAaNCMEAwHQYDVR0OBBYEFGgBk7HSSkBCaZRGLBxaiKkl
|
||||
tEdPMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
|
||||
DAUAA4ICAQCS/O64AnkXAlF9IcVJZ6ek8agkOOsMaOpaQmuc9HPBaUotszcFUEKY
|
||||
kp4GeSwuBpn2798roM2zkgGDtaDLJ7U8IxqYSaLsLZmlWUOs0rGT1lfXHLyT1sZA
|
||||
4bNvGVW3E9flQzOktavL2sExZA101iztw41u67uvGUdhYS3A9AW5b3jcOvdCQGVT
|
||||
kb2ZDZOSVKapN1krm8uZxrw99wSE8JQzHQ+CWjnLLkXDKBmjspuYyPwxa2CP9umG
|
||||
KLzgPH10XRaJW2kkxxCLxEu7Nk/UWT/DsKSRmfgu0UoBnfWIEu+/WhFqWU9Za1pn
|
||||
84+0Ew/A2C89KHKqGX8RfWpbn5XnX7eUT/E+oVr/Lcyd3yd3jzJzHGcKdvP6XLG/
|
||||
vB29DCibsscXZwszD8O9Ntz7ukILq+2Ew2LWhBapsQdrqW7uxs/msEQpwvCzYYAq
|
||||
i2/SFFwlh1Rk86RMwaH4p2vq/uo6/HnbDo/cxvPJ1Gze6YOhjh0i7Mk6sgB73Dun
|
||||
Qhp/3IupET2Op8Agb10JXUNE5o9mzKlbB/Hvm3oOs1ThlP0OLMaT11X9cZg1uAlK
|
||||
/8YpKCz2Ui3bFBiSJ+IWfozK1GG+goeR65g3P79fXXc/NKwbOEOraHKZMh46Ghml
|
||||
ozhMI9ej58zVKpIXkAtaS70WvfuGauKJmezkoFUYyaMIHxPgMghy0A==
|
||||
-----END CERTIFICATE-----
|
||||
21
make/data/cacerts/digicerttlseccrootg5
Normal file
21
make/data/cacerts/digicerttlseccrootg5
Normal file
@@ -0,0 +1,21 @@
|
||||
Owner: CN=DigiCert TLS ECC P384 Root G5, O="DigiCert, Inc.", C=US
|
||||
Issuer: CN=DigiCert TLS ECC P384 Root G5, O="DigiCert, Inc.", C=US
|
||||
Serial number: 9e09365acf7d9c8b93e1c0b042a2ef3
|
||||
Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046
|
||||
Signature algorithm name: SHA384withECDSA
|
||||
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw
|
||||
CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp
|
||||
Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2
|
||||
MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
|
||||
bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG
|
||||
ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS
|
||||
7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp
|
||||
0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS
|
||||
B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49
|
||||
BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ
|
||||
LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4
|
||||
DXZDjC5Ty3zfDBeWUA==
|
||||
-----END CERTIFICATE-----
|
||||
38
make/data/cacerts/digicerttlsrsarootg5
Normal file
38
make/data/cacerts/digicerttlsrsarootg5
Normal file
@@ -0,0 +1,38 @@
|
||||
Owner: CN=DigiCert TLS RSA4096 Root G5, O="DigiCert, Inc.", C=US
|
||||
Issuer: CN=DigiCert TLS RSA4096 Root G5, O="DigiCert, Inc.", C=US
|
||||
Serial number: 8f9b478a8fa7eda6a333789de7ccf8a
|
||||
Valid from: Fri Jan 15 00:00:00 GMT 2021 until: Sun Jan 14 23:59:59 GMT 2046
|
||||
Signature algorithm name: SHA384withRSA
|
||||
Subject Public Key Algorithm: 4096-bit RSA key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN
|
||||
MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT
|
||||
HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN
|
||||
NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs
|
||||
IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi
|
||||
MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+
|
||||
ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0
|
||||
2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp
|
||||
wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM
|
||||
pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD
|
||||
nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po
|
||||
sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx
|
||||
Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd
|
||||
Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX
|
||||
KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe
|
||||
XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL
|
||||
tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv
|
||||
TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN
|
||||
AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw
|
||||
GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H
|
||||
PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF
|
||||
O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ
|
||||
REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik
|
||||
AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv
|
||||
/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+
|
||||
p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw
|
||||
MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF
|
||||
qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK
|
||||
ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+
|
||||
-----END CERTIFICATE-----
|
||||
22
make/data/cacerts/emsigneccrootcag3
Normal file
22
make/data/cacerts/emsigneccrootcag3
Normal file
@@ -0,0 +1,22 @@
|
||||
Owner: CN=emSign ECC Root CA - G3, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN
|
||||
Issuer: CN=emSign ECC Root CA - G3, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN
|
||||
Serial number: 3cf607a968700eda8b84
|
||||
Valid from: Sun Feb 18 18:30:00 GMT 2018 until: Wed Feb 18 18:30:00 GMT 2043
|
||||
Signature algorithm name: SHA384withECDSA
|
||||
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
|
||||
EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
|
||||
bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
|
||||
RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
|
||||
TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
|
||||
b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
|
||||
djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
|
||||
WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
|
||||
fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
|
||||
zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
|
||||
hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
|
||||
CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
|
||||
+JbNR6iC8hZVdyR+EhCVBCyj
|
||||
-----END CERTIFICATE-----
|
||||
29
make/data/cacerts/emsignrootcag1
Normal file
29
make/data/cacerts/emsignrootcag1
Normal file
@@ -0,0 +1,29 @@
|
||||
Owner: CN=emSign Root CA - G1, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN
|
||||
Issuer: CN=emSign Root CA - G1, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN
|
||||
Serial number: 31f5e4620c6c58edd6d8
|
||||
Valid from: Sun Feb 18 18:30:00 GMT 2018 until: Wed Feb 18 18:30:00 GMT 2043
|
||||
Signature algorithm name: SHA256withRSA
|
||||
Subject Public Key Algorithm: 2048-bit RSA key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD
|
||||
VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU
|
||||
ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH
|
||||
MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO
|
||||
MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv
|
||||
Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz
|
||||
f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO
|
||||
8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq
|
||||
d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM
|
||||
tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt
|
||||
Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB
|
||||
o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD
|
||||
AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x
|
||||
PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM
|
||||
wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d
|
||||
GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH
|
||||
6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby
|
||||
RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
|
||||
iN66zB+Afko=
|
||||
-----END CERTIFICATE-----
|
||||
39
make/data/cacerts/emsignrootcag2
Normal file
39
make/data/cacerts/emsignrootcag2
Normal file
@@ -0,0 +1,39 @@
|
||||
Owner: CN=emSign Root CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN
|
||||
Issuer: CN=emSign Root CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN
|
||||
Serial number: 864dbf0fe35ed77d8ed8
|
||||
Valid from: Sun Feb 18 18:30:00 GMT 2018 until: Wed Feb 18 18:30:00 GMT 2043
|
||||
Signature algorithm name: SHA384withRSA
|
||||
Subject Public Key Algorithm: 4096-bit RSA key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFlTCCA32gAwIBAgILAIZNvw/jXtd9jtgwDQYJKoZIhvcNAQEMBQAwZzELMAkG
|
||||
A1UEBhMCSU4xEzARBgNVBAsTCmVtU2lnbiBQS0kxJTAjBgNVBAoTHGVNdWRocmEg
|
||||
VGVjaG5vbG9naWVzIExpbWl0ZWQxHDAaBgNVBAMTE2VtU2lnbiBSb290IENBIC0g
|
||||
RzIwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBnMQswCQYDVQQGEwJJ
|
||||
TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
|
||||
b2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMjCCAiIw
|
||||
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMNwGIWW2kHfHK+sXTNwxF07K+IV
|
||||
ySTuyFM2r1v002wUfcdT+zs5OM5QbMYFFnedXQI6gCFLsjKrcaej48Zt37OyEb3i
|
||||
aPs7CsP4kAyTwzKH9aZe6gXYHrJq40/ZVMNcQVI2PcIp40B/SAN2gUZ+ZaUtIOvV
|
||||
jEx26/ebNaXRIsthlkOG/caB+QRwDw1tl7338Zlv0M2oTBUy4B3e7dGP5pgXH71M
|
||||
jqHPCoNo+xv9f0NTBT+hUDa8h8wUtcGQq9CDeJTpjWcD2bP2AMdVG6oVpMAUeUzo
|
||||
cCyglvtFdUMjggxBbw4qhau1HXPG8Ot9hwL7ZMi8tkTzrvUIxxb8G9LF/7kKeCE7
|
||||
tGZaVzDTnXuifl3msR4ErHsQ4P7lVu2AIjIAhrAXoedDidb7pMcf7TABdrYUT1Jo
|
||||
G/AiK+J9jO6GTjeADD4LMDSBZhHMuBK/PJ/g0kGBt+/C1L+/HURzQhJkMlRnM6Rv
|
||||
XoCtfKopSlns5trZmTi971Wjbn88QXP61lGpBCUPwCjs7rpOYvSUJtI+lcbF+37q
|
||||
kIqOXYkVT3cupDSpw+H89kFtj5GKY+Xny4LxY+3IvDIRiyd6ky1DPj713DI0yqve
|
||||
EpsIr3A0PdwuyUI7CS1jg0NnGFT6Xxyr0xB+VDt83FJYW8v16k2pbaQ4kVxA3aXd
|
||||
X9dZYyVR1S59KM75AgMBAAGjQjBAMB0GA1UdDgQWBBTt7E1FYRgo57MjKBEcTaUn
|
||||
DV7s9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
|
||||
AQwFAAOCAgEACFC/ilQg8KTCVBxFJW/sazomkS0kNYbEIZg4B3obqwsJ7SX98z8Z
|
||||
gfzBpz0nYClwwJjWbFN1R2zY8pCEot6/dgmA8Vbq0GxhwPM5YN/SZquNyRIxO3cU
|
||||
dlAcwf+vSezdVCf9wOzvSAF3q0a5ljvbdbNJNpfScQVp7UUd5sBsZk8jXO1KQ/go
|
||||
/Vf/GDPnrIFmxpAIGE3sgnO8lAv9FzUaAeuv7HWe47xN9J7+bQzF93yHuIXACPTL
|
||||
pQHhg2zMv5C7BAbuDHfbj1Cu294Z832yhSfBcziWGskOvl3es2EcHytbS9c9P+0z
|
||||
Mpka7zGC1FHrvLb/FoduH86TeZt0QjZ6pcplNzoaxDnDvzTJ6CC2Eny+qH/APFCu
|
||||
VUv5/wjwF+HPm8Pup2ARj9cEp92+0qcerfHacNq5hMeGZdbA/dzdUR/5z5zXdxAk
|
||||
nl8mcfGb0eMNSTXQmmB/i4AecNnr72uYjzlaXUGYN7Nrb6XouG0pnh0/BBtWWp0U
|
||||
ShIPpWEAqs7RJBj6+1ZUYXZ4ObrCw962DxhN2p19Hxw9LtuUUcLqqTPrFXYvwO4t
|
||||
ouj7KJnAkaTUfXGdEaFVtFig1EA30WzJY2X1vAQ7hVnniCjgaXAGqjsU6sklNM9n
|
||||
xDx5rFCCCEtj9Kh8UHjGK2QqgP5kwgttjOApQMaCoezMfK4KD7WpOXU=
|
||||
-----END CERTIFICATE-----
|
||||
21
make/data/cacerts/letsencryptisrgx2
Normal file
21
make/data/cacerts/letsencryptisrgx2
Normal file
@@ -0,0 +1,21 @@
|
||||
Owner: CN=ISRG Root X2, O=Internet Security Research Group, C=US
|
||||
Issuer: CN=ISRG Root X2, O=Internet Security Research Group, C=US
|
||||
Serial number: 41d29dd172eaeea780c12c6ce92f8752
|
||||
Valid from: Fri Sep 04 00:00:00 GMT 2020 until: Mon Sep 17 16:00:00 GMT 2040
|
||||
Signature algorithm name: SHA384withECDSA
|
||||
Subject Public Key Algorithm: 384-bit EC (secp384r1) key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
|
||||
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
|
||||
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
|
||||
MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
|
||||
ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
|
||||
EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
|
||||
+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
|
||||
ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
|
||||
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
|
||||
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
|
||||
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
|
||||
/q4AaOeMSQ+2b1tbFfLn
|
||||
-----END CERTIFICATE-----
|
||||
39
make/data/cacerts/teliarootcav2
Normal file
39
make/data/cacerts/teliarootcav2
Normal file
@@ -0,0 +1,39 @@
|
||||
Owner: CN=Telia Root CA v2, O=Telia Finland Oyj, C=FI
|
||||
Issuer: CN=Telia Root CA v2, O=Telia Finland Oyj, C=FI
|
||||
Serial number: 1675f27d6fe7ae3e4acbe095b059e
|
||||
Valid from: Thu Nov 29 11:55:54 GMT 2018 until: Sun Nov 29 11:55:54 GMT 2043
|
||||
Signature algorithm name: SHA256withRSA
|
||||
Subject Public Key Algorithm: 4096-bit RSA key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx
|
||||
CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE
|
||||
AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1
|
||||
NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ
|
||||
MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
|
||||
ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq
|
||||
AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9
|
||||
vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9
|
||||
lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD
|
||||
n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT
|
||||
7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o
|
||||
6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC
|
||||
TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6
|
||||
WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R
|
||||
DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI
|
||||
pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj
|
||||
YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy
|
||||
rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
|
||||
AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ
|
||||
8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi
|
||||
0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM
|
||||
A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS
|
||||
SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K
|
||||
TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF
|
||||
6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er
|
||||
3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt
|
||||
Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT
|
||||
VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW
|
||||
ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA
|
||||
rBPuUBQemMc=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -40,10 +40,22 @@ mkdir -p $BUILD_DIR $JAR_DIR
|
||||
cd $JAR_DIR
|
||||
rm -f *
|
||||
|
||||
wget https://repo.maven.apache.org/maven2/org/apache/commons/commons-math3/$COMMONS_MATH3_VERSION/commons-math3-$COMMONS_MATH3_VERSION.jar
|
||||
wget https://repo.maven.apache.org/maven2/net/sf/jopt-simple/jopt-simple/$JOPT_SIMPLE_VERSION/jopt-simple-$JOPT_SIMPLE_VERSION.jar
|
||||
wget https://repo.maven.apache.org/maven2/org/openjdk/jmh/jmh-core/$JMH_VERSION/jmh-core-$JMH_VERSION.jar
|
||||
wget https://repo.maven.apache.org/maven2/org/openjdk/jmh/jmh-generator-annprocess/$JMH_VERSION/jmh-generator-annprocess-$JMH_VERSION.jar
|
||||
fetchJar() {
|
||||
url="https://repo.maven.apache.org/maven2/$1/$2/$3/$2-$3.jar"
|
||||
if command -v curl > /dev/null; then
|
||||
curl -O --fail $url
|
||||
elif command -v wget > /dev/null; then
|
||||
wget $url
|
||||
else
|
||||
echo "Could not find either curl or wget"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
fetchJar org/apache/commons commons-math3 $COMMONS_MATH3_VERSION
|
||||
fetchJar net/sf/jopt-simple jopt-simple $JOPT_SIMPLE_VERSION
|
||||
fetchJar org/openjdk/jmh jmh-core $JMH_VERSION
|
||||
fetchJar org/openjdk/jmh jmh-generator-annprocess $JMH_VERSION
|
||||
|
||||
tar -cvzf ../$BUNDLE_NAME *
|
||||
|
||||
|
||||
@@ -519,7 +519,7 @@ else
|
||||
LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc
|
||||
|
||||
HARFBUZZ_DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing \
|
||||
array-bounds
|
||||
array-bounds parentheses
|
||||
# noexcept-type required for GCC 7 builds. Not required for GCC 8+.
|
||||
# expansion-to-defined required for GCC 9 builds. Not required for GCC 10+.
|
||||
HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2016, 2023 Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -27,7 +27,7 @@ include LibCommon.gmk
|
||||
|
||||
################################################################################
|
||||
|
||||
ifeq ($(call isTargetOs, linux macosx), true)
|
||||
ifeq ($(call isTargetOs, linux macosx windows), true)
|
||||
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIBEXTNET, \
|
||||
NAME := extnet, \
|
||||
@@ -35,8 +35,9 @@ ifeq ($(call isTargetOs, linux macosx), true)
|
||||
CFLAGS := $(CFLAGS_JDKLIB), \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LIBS := -ljava, \
|
||||
LIBS_unix := -ljava, \
|
||||
LIBS_linux := -ljvm, \
|
||||
LIBS_windows := jvm.lib ws2_32.lib $(WIN_JAVA_LIB), \
|
||||
))
|
||||
|
||||
$(BUILD_LIBEXTNET): $(call FindLib, java.base, java)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@@ -36,9 +36,11 @@ TEST_LIB_SUPPORT := $(SUPPORT_OUTPUTDIR)/test/lib
|
||||
|
||||
$(eval $(call SetupJavaCompilation, BUILD_WB_JAR, \
|
||||
TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \
|
||||
SRC := $(TEST_LIB_SOURCE_DIR)/sun, \
|
||||
SRC := $(TEST_LIB_SOURCE_DIR)/jdk/test/whitebox/, \
|
||||
BIN := $(TEST_LIB_SUPPORT)/wb_classes, \
|
||||
JAR := $(TEST_LIB_SUPPORT)/wb.jar, \
|
||||
DISABLED_WARNINGS := deprecation removal preview, \
|
||||
JAVAC_FLAGS := --enable-preview, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_WB_JAR)
|
||||
@@ -50,7 +52,14 @@ $(eval $(call SetupJavaCompilation, BUILD_TEST_LIB_JAR, \
|
||||
BIN := $(TEST_LIB_SUPPORT)/test-lib_classes, \
|
||||
HEADERS := $(TEST_LIB_SUPPORT)/test-lib_headers, \
|
||||
JAR := $(TEST_LIB_SUPPORT)/test-lib.jar, \
|
||||
DISABLED_WARNINGS := try deprecation rawtypes unchecked serial cast, \
|
||||
DISABLED_WARNINGS := try deprecation rawtypes unchecked serial cast removal preview, \
|
||||
JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.classfile=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.classfile.attribute=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.classfile.java.lang.constant=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
|
||||
--enable-preview, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_TEST_LIB_JAR)
|
||||
|
||||
@@ -66,9 +66,11 @@ ifeq ($(call isTargetOs, windows), true)
|
||||
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := jvm.lib
|
||||
BUILD_JDK_JTREG_EXECUTABLES_LIBS_exerevokeall := advapi32.lib
|
||||
BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libAsyncStackWalk := /EHsc
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libGetXSpace := $(WIN_LIB_JAVA)
|
||||
else
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := -ljava
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libDirectIO := -ljava
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libGetXSpace := -ljava
|
||||
BUILD_JDK_JTREG_EXCLUDE += exerevokeall.c
|
||||
ifeq ($(call isTargetOs, linux), true)
|
||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# - Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# - Neither the name of Oracle nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
SOURCEPATH=src
|
||||
CLASSES=build
|
||||
DIST=dist
|
||||
RESOURCES=resources
|
||||
|
||||
RENDERPERF_CLASSES = $(CLASSES)/renderperf/RenderPerfTest.class
|
||||
RENDERPERF_SOURCES = $(SOURCEPATH)/renderperf/RenderPerfTest.java
|
||||
|
||||
RENDERPERF_RESOURCES = $(CLASSES)/renderperf/images/duke.png
|
||||
|
||||
all: mkdirs $(DIST)/RenderPerfTest.jar
|
||||
|
||||
run: mkdirs $(DIST)/RenderPerfTest.jar
|
||||
java -jar $(DIST)/RenderPerfTest.jar
|
||||
|
||||
$(DIST)/RenderPerfTest.jar: \
|
||||
$(RENDERPERF_CLASSES) $(RENDERPERF_RESOURCES) \
|
||||
$(CLASSES)/renderperf.manifest
|
||||
jar cvmf $(CLASSES)/renderperf.manifest $(DIST)/RenderPerfTest.jar -C $(CLASSES) .
|
||||
|
||||
|
||||
$(CLASSES)/renderperf/images/%: $(RESOURCES)/images/%
|
||||
cp -r $< $@
|
||||
|
||||
|
||||
$(CLASSES)/renderperf.manifest:
|
||||
echo "Main-Class: renderperf.RenderPerfTest" > $@
|
||||
|
||||
$(DIST):
|
||||
mkdir $(DIST)
|
||||
|
||||
$(CLASSES):
|
||||
mkdir $(CLASSES)
|
||||
mkdir -p $(CLASSES)/renderperf/images
|
||||
|
||||
mkdirs: $(DIST) $(CLASSES)
|
||||
|
||||
$(RENDERPERF_CLASSES): $(RENDERPERF_SOURCES)
|
||||
javac -g:none -d $(CLASSES) -sourcepath $(SOURCEPATH) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(CLASSES)
|
||||
rm -rf $(DIST)
|
||||
@@ -1,34 +0,0 @@
|
||||
-----------------------------------------------------------------------
|
||||
Introduction
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
RenderPerfTest is a set of on-screen rendering microbenchmarks to
|
||||
analyze the performance of Java2D graphical primitives rendering
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
How To Compile
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
#> cd RenderPerfTest
|
||||
|
||||
The benchmark can be compiled by using either ant:
|
||||
|
||||
#> ant
|
||||
|
||||
or gnumake (assuming there's 'javac' in the path):
|
||||
|
||||
#> gnumake
|
||||
|
||||
The jar files will be generated into RenderPerfTest/dist directory.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
How To Run RenderPerfTest
|
||||
-----------------------------------------------------------------------
|
||||
Run all tests
|
||||
#> ant run
|
||||
or
|
||||
#> java -jar dist/RenderPerfTest.jar
|
||||
|
||||
Run particular test cases
|
||||
|
||||
#> java -jar dist/RenderPerfTest.jar testWhiteTextBubblesGray ...
|
||||
@@ -1,94 +0,0 @@
|
||||
<!--
|
||||
Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of Oracle nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
|
||||
<project name="RenderPerfTest" default="dist" basedir=".">
|
||||
<description>
|
||||
simple example build file
|
||||
</description>
|
||||
<!-- set global properties for this build -->
|
||||
<property name="src" location="src"/>
|
||||
<property name="build" location="build"/>
|
||||
<property name="dist" location="dist"/>
|
||||
<property name="resources" location="resources"/>
|
||||
|
||||
<target name="init">
|
||||
<!-- Create the time stamp -->
|
||||
<tstamp/>
|
||||
<!-- Create the build directory structure used by compile -->
|
||||
<mkdir dir="${build}"/>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init"
|
||||
description="compile the source " >
|
||||
<!-- Compile the java code from ${src} into ${build} -->
|
||||
<javac includeantruntime="false" debug="off" srcdir="${src}" destdir="${build}"/>
|
||||
</target>
|
||||
|
||||
<target name="run" depends="dist"
|
||||
description="run RenderPerfTest" >
|
||||
<java jar="${dist}/RenderPerfTest.jar"
|
||||
fork="true"
|
||||
>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="resources" depends="init"
|
||||
description="copy resources into build dir" >
|
||||
<!-- Copy the resource files from ${resources} into ${build}/ -->
|
||||
<mkdir dir="${dist}"/>
|
||||
<mkdir dir="${dist}/renderperf"/>
|
||||
<mkdir dir="${build}/renderperf/images"/>
|
||||
<copy todir="${build}/renderperf/images">
|
||||
<fileset dir="resources/renderperf/images" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="compile, resources"
|
||||
description="generate the distribution" >
|
||||
<!-- Create the distribution directory -->
|
||||
<mkdir dir="${dist}"/>
|
||||
|
||||
<!-- Put everything in ${build} into the J2DBench.jar file -->
|
||||
<jar jarfile="${dist}/RenderPerfTest.jar" basedir="${build}">
|
||||
<manifest>
|
||||
<attribute name="Built-By" value="${user.name}"/>
|
||||
<attribute name="Main-Class" value="renderperf.RenderPerfTest"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="clean"
|
||||
description="clean up" >
|
||||
<!-- Delete the ${build} and ${dist} directory trees -->
|
||||
<delete dir="${build}"/>
|
||||
<delete dir="${dist}"/>
|
||||
</target>
|
||||
</project>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,739 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2020 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package renderperf;
|
||||
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
||||
public class RenderPerfTest {
|
||||
private static HashSet<String> ignoredTests = new HashSet<>();
|
||||
|
||||
private final static int N = 1000;
|
||||
private final static float WIDTH = 800;
|
||||
private final static float HEIGHT = 800;
|
||||
private final static float R = 25;
|
||||
private final static int BW = 50;
|
||||
private final static int BH = 50;
|
||||
private final static int COUNT = 300;
|
||||
private final static int DELAY = 10;
|
||||
private final static int RESOLUTION = 5;
|
||||
private final static int COLOR_TOLERANCE = 10;
|
||||
private final static int MAX_MEASURE_TIME = 5000;
|
||||
|
||||
|
||||
interface Configurable {
|
||||
void configure(Graphics2D g2d);
|
||||
}
|
||||
|
||||
interface Renderable {
|
||||
void setup(Graphics2D g2d);
|
||||
void render(Graphics2D g2d);
|
||||
void update();
|
||||
}
|
||||
|
||||
static class Particles {
|
||||
private float[] bx;
|
||||
private float[] by;
|
||||
private float[] vx;
|
||||
private float[] vy;
|
||||
private float r;
|
||||
private int n;
|
||||
|
||||
private float x0;
|
||||
private float y0;
|
||||
private float width;
|
||||
private float height;
|
||||
|
||||
Particles(int n, float r, float x0, float y0, float width, float height) {
|
||||
bx = new float[n];
|
||||
by = new float[n];
|
||||
vx = new float[n];
|
||||
vy = new float[n];
|
||||
this.n = n;
|
||||
this.r = r;
|
||||
this.x0 = x0;
|
||||
this.y0 = y0;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
for (int i = 0; i < n; i++) {
|
||||
bx[i] = (float) (x0 + r + 0.1 + Math.random() * (width - 2 * r - 0.2 - x0));
|
||||
by[i] = (float) (y0 + r + 0.1 + Math.random() * (height - 2 * r - 0.2 - y0));
|
||||
vx[i] = 0.1f * (float) (Math.random() * 2 * r - r);
|
||||
vy[i] = 0.1f * (float) (Math.random() * 2 * r - r);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void render(Graphics2D g2d, ParticleRenderer renderer) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
renderer.render(g2d, i, bx, by, vx, vy);
|
||||
}
|
||||
}
|
||||
|
||||
void update() {
|
||||
for (int i = 0; i < n; i++) {
|
||||
bx[i] += vx[i];
|
||||
if (bx[i] + r > width || bx[i] - r < x0) vx[i] = -vx[i];
|
||||
by[i] += vy[i];
|
||||
if (by[i] + r > height || by[i] - r < y0) vy[i] = -vy[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ParticleRenderable createPR(ParticleRenderer renderer) {
|
||||
return new ParticleRenderable(renderer);
|
||||
}
|
||||
|
||||
static class ParticleRenderable implements Renderable {
|
||||
ParticleRenderer renderer;
|
||||
Configurable configure;
|
||||
|
||||
ParticleRenderable(ParticleRenderer renderer, Configurable configure) {
|
||||
this.renderer = renderer;
|
||||
this.configure = configure;
|
||||
}
|
||||
|
||||
ParticleRenderable(ParticleRenderer renderer) {
|
||||
this(renderer, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(Graphics2D g2d) {
|
||||
if (configure != null) configure.configure(g2d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d) {
|
||||
balls.render(g2d, renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
balls.update();
|
||||
}
|
||||
|
||||
public ParticleRenderable configure(Configurable configure) {
|
||||
this.configure = configure;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
interface ParticleRenderer {
|
||||
void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy);
|
||||
|
||||
}
|
||||
|
||||
static class FlatParticleRenderer implements ParticleRenderer {
|
||||
Color[] colors;
|
||||
float r;
|
||||
|
||||
FlatParticleRenderer(int n, float r) {
|
||||
colors = new Color[n];
|
||||
this.r = r;
|
||||
for (int i = 0; i < n; i++) {
|
||||
colors[i] = new Color((float) Math.random(),
|
||||
(float) Math.random(), (float) Math.random());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
g2d.fillOval((int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class WhiteTextParticleRenderer implements ParticleRenderer {
|
||||
float r;
|
||||
|
||||
WhiteTextParticleRenderer(float r) {
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
void setPaint(Graphics2D g2d, int id) {
|
||||
g2d.setColor(Color.WHITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
setPaint(g2d, id);
|
||||
g2d.drawString("The quick brown fox jumps over the lazy dog",
|
||||
(int)(x[id] - r), (int)(y[id] - r));
|
||||
g2d.drawString("The quick brown fox jumps over the lazy dog",
|
||||
(int)(x[id] - r), (int)y[id]);
|
||||
g2d.drawString("The quick brown fox jumps over the lazy dog",
|
||||
(int)(x[id] - r), (int)(y[id] + r));
|
||||
}
|
||||
}
|
||||
|
||||
static class TextParticleRenderer extends WhiteTextParticleRenderer {
|
||||
Color[] colors;
|
||||
|
||||
float r;
|
||||
|
||||
TextParticleRenderer(int n, float r) {
|
||||
super(r);
|
||||
colors = new Color[n];
|
||||
this.r = r;
|
||||
for (int i = 0; i < n; i++) {
|
||||
colors[i] = new Color((float) Math.random(),
|
||||
(float) Math.random(), (float) Math.random());
|
||||
}
|
||||
}
|
||||
|
||||
void setPaint(Graphics2D g2d, int id) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
}
|
||||
}
|
||||
|
||||
static class LargeTextParticleRenderer extends TextParticleRenderer {
|
||||
|
||||
LargeTextParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
setPaint(g2d, id);
|
||||
Font font = new Font("LucidaGrande", Font.PLAIN, 32);
|
||||
g2d.setFont(font);
|
||||
g2d.drawString("The quick brown fox jumps over the lazy dog",
|
||||
(int)(x[id] - r), (int)(y[id] - r));
|
||||
g2d.drawString("The quick brown fox jumps over the lazy dog",
|
||||
(int)(x[id] - r), (int)y[id]);
|
||||
g2d.drawString("The quick brown fox jumps over the lazy dog",
|
||||
(int)(x[id] - r), (int)(y[id] + r));
|
||||
}
|
||||
}
|
||||
|
||||
static class FlatOvalRotParticleRenderer extends FlatParticleRenderer {
|
||||
|
||||
|
||||
FlatOvalRotParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
|
||||
void setPaint(Graphics2D g2d, int id) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
setPaint(g2d, id);
|
||||
if (Math.abs(vx[id] + vy[id]) > 0.001) {
|
||||
AffineTransform t = (AffineTransform) g2d.getTransform().clone();
|
||||
double l = vx[id] / Math.sqrt(vx[id] * vx[id] + vy[id] * vy[id]);
|
||||
if (vy[id] < 0) {
|
||||
l = -l;
|
||||
}
|
||||
g2d.translate(x[id], y[id]);
|
||||
g2d.rotate(Math.acos(l));
|
||||
g2d.fillOval(-(int)r, (int)(-0.5*r), (int) (2 * r), (int)r);
|
||||
g2d.setTransform(t);
|
||||
} else {
|
||||
g2d.fillOval((int)(x[id] - r), (int)(y[id] - 0.5*r),
|
||||
(int) (2 * r), (int) r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class LinGradOvalRotParticleRenderer extends FlatOvalRotParticleRenderer {
|
||||
|
||||
|
||||
LinGradOvalRotParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
void setPaint(Graphics2D g2d, int id) {
|
||||
Point2D start = new Point2D.Double(- r, - 0.5*r);
|
||||
Point2D end = new Point2D.Double( 2 * r, r);
|
||||
float[] dist = {0.0f, 1.0f};
|
||||
Color[] cls = {colors[id %colors.length], colors[(colors.length - id) %colors.length]};
|
||||
LinearGradientPaint p =
|
||||
new LinearGradientPaint(start, end, dist, cls);
|
||||
g2d.setPaint(p);
|
||||
}
|
||||
}
|
||||
|
||||
static class FlatBoxParticleRenderer extends FlatParticleRenderer {
|
||||
|
||||
|
||||
FlatBoxParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
g2d.fillRect((int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class ImgParticleRenderer extends FlatParticleRenderer {
|
||||
BufferedImage dukeImg;
|
||||
|
||||
ImgParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
try {
|
||||
dukeImg = ImageIO.read(
|
||||
Objects.requireNonNull(
|
||||
RenderPerfTest.class.getClassLoader().getResourceAsStream(
|
||||
"renderperf/images/duke.png")));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
g2d.drawImage(dukeImg, (int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r), null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class FlatBoxRotParticleRenderer extends FlatParticleRenderer {
|
||||
|
||||
|
||||
FlatBoxRotParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
if (Math.abs(vx[id] + vy[id]) > 0.001) {
|
||||
AffineTransform t = (AffineTransform) g2d.getTransform().clone();
|
||||
double l = vx[id] / Math.sqrt(vx[id] * vx[id] + vy[id] * vy[id]);
|
||||
if (vy[id] < 0) {
|
||||
l = -l;
|
||||
}
|
||||
g2d.translate(x[id], y[id]);
|
||||
g2d.rotate(Math.acos(l));
|
||||
g2d.fillRect(-(int)r, -(int)r, (int) (2 * r), (int) (2 * r));
|
||||
g2d.setTransform(t);
|
||||
} else {
|
||||
g2d.fillRect((int)(x[id] - r), (int)(y[id] - r),
|
||||
(int) (2 * r), (int) (2 * r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class WiredParticleRenderer extends FlatParticleRenderer {
|
||||
|
||||
|
||||
WiredParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
g2d.drawOval((int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r));
|
||||
}
|
||||
|
||||
}
|
||||
static class WiredBoxParticleRenderer extends FlatParticleRenderer {
|
||||
|
||||
WiredBoxParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
g2d.drawRect((int)(x[id] - r), (int)(y[id] - r), (int)(2*r), (int)(2*r));
|
||||
}
|
||||
|
||||
}
|
||||
static class SegParticleRenderer extends FlatParticleRenderer {
|
||||
|
||||
SegParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
double v = Math.sqrt(vx[id]*vx[id]+vy[id]*vy[id]);
|
||||
float nvx = (float) (vx[id]/v);
|
||||
float nvy = (float) (vy[id]/v);
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
g2d.drawLine((int)(x[id] - r*nvx), (int)(y[id] - r*nvy),
|
||||
(int)(x[id] + 2*r*nvx), (int)(y[id] + 2*r*nvy));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static class WiredQuadParticleRenderer extends FlatParticleRenderer {
|
||||
|
||||
WiredQuadParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
if (id > 2 && (id % 3) == 0) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
g2d.draw(new QuadCurve2D.Float(x[id-3], y[id-3], x[id-2], y[id-2], x[id-1], y[id-1]));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class FlatQuadParticleRenderer extends FlatParticleRenderer {
|
||||
|
||||
FlatQuadParticleRenderer(int n, float r) {
|
||||
super(n, r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Graphics2D g2d, int id, float[] x, float[] y, float[] vx, float[] vy) {
|
||||
if (id > 2 && (id % 3) == 0) {
|
||||
g2d.setColor(colors[id % colors.length]);
|
||||
g2d.fill(new QuadCurve2D.Float(x[id-3], y[id-3], x[id-2], y[id-2], x[id-1], y[id-1]));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static class PerfMeter {
|
||||
private String name;
|
||||
private int frame = 0;
|
||||
|
||||
private JPanel panel;
|
||||
|
||||
private long time;
|
||||
private double execTime = 0;
|
||||
private Color expColor = Color.RED;
|
||||
AtomicBoolean waiting = new AtomicBoolean(false);
|
||||
private double fps;
|
||||
|
||||
PerfMeter(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
PerfMeter exec(final Renderable renderable) throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(COUNT);
|
||||
final CountDownLatch latchFrame = new CountDownLatch(1);
|
||||
final long endTime = System.currentTimeMillis() + MAX_MEASURE_TIME;
|
||||
|
||||
final JFrame f = new JFrame();
|
||||
f.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosed(WindowEvent e) {
|
||||
latchFrame.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
panel = new JPanel()
|
||||
{
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
|
||||
super.paintComponent(g);
|
||||
time = System.nanoTime();
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
renderable.setup(g2d);
|
||||
renderable.render(g2d);
|
||||
g2d.setColor(expColor);
|
||||
g.fillRect(0, 0, BW, BH);
|
||||
}
|
||||
};
|
||||
|
||||
panel.setPreferredSize(new Dimension((int)(WIDTH + BW), (int)(HEIGHT + BH)));
|
||||
panel.setBackground(Color.BLACK);
|
||||
f.add(panel);
|
||||
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
f.pack();
|
||||
f.setVisible(true);
|
||||
}
|
||||
});
|
||||
Robot robot = new Robot();
|
||||
|
||||
Timer timer = new Timer(DELAY, e -> {
|
||||
|
||||
if (waiting.compareAndSet(false, true)) {
|
||||
Color c = robot.getPixelColor(
|
||||
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW / 2,
|
||||
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BW / 2);
|
||||
if (isAlmostEqual(c, Color.BLUE)) {
|
||||
expColor = Color.RED;
|
||||
} else {
|
||||
expColor = Color.BLUE;
|
||||
}
|
||||
renderable.update();
|
||||
panel.getParent().repaint();
|
||||
|
||||
} else {
|
||||
while (!isAlmostEqual(
|
||||
robot.getPixelColor(
|
||||
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW/2,
|
||||
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BH/2),
|
||||
expColor))
|
||||
{
|
||||
try {
|
||||
Thread.sleep(RESOLUTION);
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
time = System.nanoTime() - time;
|
||||
execTime += time;
|
||||
frame++;
|
||||
waiting.set(false);
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() < endTime) {
|
||||
latch.countDown();
|
||||
} else {
|
||||
while(latch.getCount() > 0) latch.countDown();
|
||||
}
|
||||
});
|
||||
timer.start();
|
||||
latch.await();
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
timer.stop();
|
||||
f.setVisible(false);
|
||||
f.dispose();
|
||||
});
|
||||
|
||||
latchFrame.await();
|
||||
if (execTime != 0 && frame != 0) {
|
||||
fps = 1e9 / (execTime / frame);
|
||||
} else {
|
||||
fps = 0;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private void report() {
|
||||
System.err.println(name + " : " + String.format("%.2f FPS", fps));
|
||||
}
|
||||
|
||||
private boolean isAlmostEqual(Color c1, Color c2) {
|
||||
return Math.abs(c1.getRed() - c2.getRed()) < COLOR_TOLERANCE ||
|
||||
Math.abs(c1.getGreen() - c2.getGreen()) < COLOR_TOLERANCE ||
|
||||
Math.abs(c1.getBlue() - c2.getBlue()) < COLOR_TOLERANCE;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static final Particles balls = new Particles(N, R, BW, BH, WIDTH, HEIGHT);
|
||||
private static final ParticleRenderer flatRenderer = new FlatParticleRenderer(N, R);
|
||||
private static final ParticleRenderer flatOvalRotRenderer = new FlatOvalRotParticleRenderer(N, R);
|
||||
private static final ParticleRenderer flatBoxRenderer = new FlatBoxParticleRenderer(N, R);
|
||||
private static final ParticleRenderer flatBoxRotRenderer = new FlatBoxRotParticleRenderer(N, R);
|
||||
private static final ParticleRenderer linGradOvalRotRenderer = new LinGradOvalRotParticleRenderer(N, R);
|
||||
private static final ParticleRenderer wiredRenderer = new WiredParticleRenderer(N, R);
|
||||
private static final ParticleRenderer wiredBoxRenderer = new WiredBoxParticleRenderer(N, R);
|
||||
private static final ParticleRenderer segRenderer = new SegParticleRenderer(N, R);
|
||||
private static final ParticleRenderer flatQuadRenderer = new FlatQuadParticleRenderer(N, R);
|
||||
private static final ParticleRenderer wiredQuadRenderer = new WiredQuadParticleRenderer(N, R);
|
||||
private static final ParticleRenderer imgRenderer = new ImgParticleRenderer(N, R);
|
||||
private static final ParticleRenderer textRenderer = new TextParticleRenderer(N, R);
|
||||
private static final ParticleRenderer largeTextRenderer = new LargeTextParticleRenderer(N, R);
|
||||
private static final ParticleRenderer whiteTextRenderer = new WhiteTextParticleRenderer(R);
|
||||
|
||||
private static final Configurable AA = (Graphics2D g2d) ->
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
private static final Configurable TextLCD = (Graphics2D g2d) ->
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
|
||||
|
||||
private static final Configurable TextAA = (Graphics2D g2d) ->
|
||||
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
|
||||
public void testFlatBubbles() throws Exception {
|
||||
(new PerfMeter("FlatOval")).exec(createPR(flatRenderer)).report();
|
||||
}
|
||||
|
||||
public void testFlatBubblesAA() throws Exception {
|
||||
(new PerfMeter("FlatOvalAA")).exec(createPR(flatRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testFlatBoxBubbles() throws Exception {
|
||||
(new PerfMeter("FlatBox")).exec(createPR(flatBoxRenderer)).report();
|
||||
}
|
||||
|
||||
public void testFlatBoxBubblesAA() throws Exception {
|
||||
(new PerfMeter("FlatBoxAA")).exec(createPR(flatBoxRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testImgBubbles() throws Exception {
|
||||
(new PerfMeter("Image")).exec(createPR(imgRenderer)).report();
|
||||
}
|
||||
|
||||
public void testImgBubblesAA() throws Exception {
|
||||
(new PerfMeter("ImageAA")).exec(createPR(imgRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testFlatBoxRotBubbles() throws Exception {
|
||||
(new PerfMeter("RotatedBox")).exec(createPR(flatBoxRotRenderer)).report();
|
||||
}
|
||||
|
||||
public void testFlatBoxRotBubblesAA() throws Exception {
|
||||
(new PerfMeter("RotatedBoxAA")).exec(createPR(flatBoxRotRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testFlatOvalRotBubbles() throws Exception {
|
||||
(new PerfMeter("RotatedOval")).exec(createPR(flatOvalRotRenderer)).report();
|
||||
}
|
||||
|
||||
public void testFlatOvalRotBubblesAA() throws Exception {
|
||||
(new PerfMeter("RotatedOvalAA")).exec(createPR(flatOvalRotRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testLinGradOvalRotBubbles() throws Exception {
|
||||
(new PerfMeter("LinGradRotatedOval")).exec(createPR(linGradOvalRotRenderer)).report();
|
||||
}
|
||||
|
||||
public void testLinGradOvalRotBubblesAA() throws Exception {
|
||||
(new PerfMeter("LinGradRotatedOvalAA")).exec(createPR(linGradOvalRotRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testWiredBubbles() throws Exception {
|
||||
(new PerfMeter("WiredBubbles")).exec(createPR(wiredRenderer)).report();
|
||||
}
|
||||
|
||||
public void testWiredBubblesAA() throws Exception {
|
||||
(new PerfMeter("WiredBubblesAA")).exec(createPR(wiredRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testWiredBoxBubbles() throws Exception {
|
||||
(new PerfMeter("WiredBox")).exec(createPR(wiredBoxRenderer)).report();
|
||||
}
|
||||
|
||||
public void testWiredBoxBubblesAA() throws Exception {
|
||||
(new PerfMeter("WiredBoxAA")).exec(createPR(wiredBoxRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testLines() throws Exception {
|
||||
(new PerfMeter("Lines")).exec(createPR(segRenderer)).report();
|
||||
}
|
||||
|
||||
public void testLinesAA() throws Exception {
|
||||
(new PerfMeter("LinesAA")).exec(createPR(segRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testFlatQuad() throws Exception {
|
||||
(new PerfMeter("FlatQuad")).exec(createPR(flatQuadRenderer)).report();
|
||||
}
|
||||
|
||||
public void testFlatQuadAA() throws Exception {
|
||||
(new PerfMeter("FlatQuadAA")).exec(createPR(flatQuadRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testWiredQuad() throws Exception {
|
||||
(new PerfMeter("WiredQuad")).exec(createPR(wiredQuadRenderer)).report();
|
||||
}
|
||||
|
||||
public void testWiredQuadAA() throws Exception {
|
||||
(new PerfMeter("WiredQuadAA")).exec(createPR(wiredQuadRenderer).configure(AA)).report();
|
||||
}
|
||||
|
||||
public void testTextBubblesNoAA() throws Exception {
|
||||
(new PerfMeter("TextNoAA")).exec(createPR(textRenderer)).report();
|
||||
}
|
||||
|
||||
public void testTextBubblesLCD() throws Exception {
|
||||
(new PerfMeter("TextLCD")).exec(createPR(textRenderer).configure(TextLCD)).report();
|
||||
}
|
||||
|
||||
public void testTextBubblesGray() throws Exception {
|
||||
(new PerfMeter("TextGray")).exec(createPR(textRenderer).configure(TextAA)).report();
|
||||
}
|
||||
|
||||
public void testLargeTextBubblesNoAA() throws Exception {
|
||||
(new PerfMeter("LargeTextNoAA")).exec(createPR(largeTextRenderer)).report();
|
||||
}
|
||||
|
||||
public void testLargeTextBubblesLCD() throws Exception {
|
||||
(new PerfMeter("LargeTextLCD")).exec(createPR(largeTextRenderer).configure(TextLCD)).report();
|
||||
}
|
||||
|
||||
public void testLargeTextBubblesGray() throws Exception {
|
||||
(new PerfMeter("LargeTextGray")).exec(createPR(largeTextRenderer).configure(TextAA)).report();
|
||||
}
|
||||
public void testWhiteTextBubblesNoAA() throws Exception {
|
||||
(new PerfMeter("WhiteTextNoAA")).exec(createPR(whiteTextRenderer)).report();
|
||||
}
|
||||
|
||||
public void testWhiteTextBubblesLCD() throws Exception {
|
||||
(new PerfMeter("WhiteTextLCD")).exec(createPR(whiteTextRenderer).configure(TextLCD)).report();
|
||||
}
|
||||
|
||||
public void testWhiteTextBubblesGray() throws Exception {
|
||||
(new PerfMeter("WhiteTextGray")).exec(createPR(whiteTextRenderer).configure(TextAA)).report();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
throws InvocationTargetException, IllegalAccessException, NoSuchMethodException
|
||||
{
|
||||
RenderPerfTest test = new RenderPerfTest();
|
||||
|
||||
if (args.length > 0) {
|
||||
for (String testCase : args) {
|
||||
Method m = RenderPerfTest.class.getDeclaredMethod(testCase);
|
||||
m.invoke(test);
|
||||
}
|
||||
} else {
|
||||
Method[] methods = RenderPerfTest.class.getDeclaredMethods();
|
||||
for (Method m : methods) {
|
||||
if (m.getName().startsWith("test") && !ignoredTests.contains(m.getName())) {
|
||||
m.invoke(test);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,6 @@ inline intptr_t* frame::interpreter_frame_mdp_addr() const {
|
||||
return (intptr_t*) &(get_ijava_state()->mdx);
|
||||
}
|
||||
|
||||
// Pointer beyond the "oldest/deepest" BasicObjectLock on stack.
|
||||
inline BasicObjectLock* frame::interpreter_frame_monitor_end() const {
|
||||
return (BasicObjectLock*) get_ijava_state()->monitors;
|
||||
}
|
||||
|
||||
@@ -1933,7 +1933,7 @@ void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register
|
||||
}
|
||||
}
|
||||
|
||||
// Add a InterpMonitorElem to stack (see frame_sparc.hpp).
|
||||
// Add a monitor (see frame_ppc.hpp).
|
||||
void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2) {
|
||||
|
||||
// Very-local scratch registers.
|
||||
|
||||
@@ -4045,90 +4045,78 @@ void TemplateTable::athrow() {
|
||||
// at next monitor exit.
|
||||
void TemplateTable::monitorenter() {
|
||||
transition(atos, vtos);
|
||||
|
||||
__ verify_oop(R17_tos);
|
||||
|
||||
Register Rcurrent_monitor = R11_scratch1,
|
||||
Rcurrent_obj = R12_scratch2,
|
||||
Register Rcurrent_monitor = R3_ARG1,
|
||||
Rcurrent_obj = R4_ARG2,
|
||||
Robj_to_lock = R17_tos,
|
||||
Rscratch1 = R3_ARG1,
|
||||
Rscratch2 = R4_ARG2,
|
||||
Rscratch3 = R5_ARG3,
|
||||
Rcurrent_obj_addr = R6_ARG4;
|
||||
Rscratch1 = R11_scratch1,
|
||||
Rscratch2 = R12_scratch2,
|
||||
Rbot = R5_ARG3,
|
||||
Rfree_slot = R6_ARG4;
|
||||
|
||||
Label Lfound, Lallocate_new;
|
||||
|
||||
__ ld(Rscratch1, _abi0(callers_sp), R1_SP); // load FP
|
||||
__ li(Rfree_slot, 0); // Points to free slot or null.
|
||||
|
||||
// Set up search loop - start with topmost monitor.
|
||||
__ mr(Rcurrent_monitor, R26_monitor);
|
||||
__ addi(Rbot, Rscratch1, -frame::ijava_state_size);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Null pointer exception.
|
||||
__ null_check_throw(Robj_to_lock, -1, R11_scratch1);
|
||||
__ null_check_throw(Robj_to_lock, -1, Rscratch1);
|
||||
|
||||
// Try to acquire a lock on the object.
|
||||
// Repeat until succeeded (i.e., until monitorenter returns true).
|
||||
// Check if any slot is present => short cut to allocation if not.
|
||||
__ cmpld(CCR0, Rcurrent_monitor, Rbot);
|
||||
__ beq(CCR0, Lallocate_new);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Find a free slot in the monitor block.
|
||||
Label Lfound, Lexit, Lallocate_new;
|
||||
ConditionRegister found_free_slot = CCR0,
|
||||
found_same_obj = CCR1,
|
||||
reached_limit = CCR6;
|
||||
// Note: The order of the monitors is important for C2 OSR which derives the
|
||||
// unlock order from it (see comments for interpreter_frame_monitor_*).
|
||||
{
|
||||
Label Lloop;
|
||||
Register Rlimit = Rcurrent_monitor;
|
||||
Label Lloop, LnotFree, Lexit;
|
||||
|
||||
// Set up search loop - start with topmost monitor.
|
||||
__ add(Rcurrent_obj_addr, BasicObjectLock::obj_offset_in_bytes(), R26_monitor);
|
||||
|
||||
__ ld(Rlimit, 0, R1_SP);
|
||||
__ addi(Rlimit, Rlimit, - (frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes() - BasicObjectLock::obj_offset_in_bytes())); // Monitor base
|
||||
|
||||
// Check if any slot is present => short cut to allocation if not.
|
||||
__ cmpld(reached_limit, Rcurrent_obj_addr, Rlimit);
|
||||
__ bgt(reached_limit, Lallocate_new);
|
||||
|
||||
// Pre-load topmost slot.
|
||||
__ ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
|
||||
__ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize);
|
||||
// The search loop.
|
||||
__ bind(Lloop);
|
||||
// Found free slot?
|
||||
__ cmpdi(found_free_slot, Rcurrent_obj, 0);
|
||||
// Is this entry for same obj? If so, stop the search and take the found
|
||||
// free slot or allocate a new one to enable recursive locking.
|
||||
__ cmpd(found_same_obj, Rcurrent_obj, Robj_to_lock);
|
||||
__ cmpld(reached_limit, Rcurrent_obj_addr, Rlimit);
|
||||
__ beq(found_free_slot, Lexit);
|
||||
__ beq(found_same_obj, Lallocate_new);
|
||||
__ bgt(reached_limit, Lallocate_new);
|
||||
// Check if last allocated BasicLockObj reached.
|
||||
__ ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
|
||||
__ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize);
|
||||
// Next iteration if unchecked BasicObjectLocks exist on the stack.
|
||||
__ b(Lloop);
|
||||
__ ld(Rcurrent_obj, BasicObjectLock::obj_offset_in_bytes(), Rcurrent_monitor);
|
||||
// Exit if current entry is for same object; this guarantees, that new monitor
|
||||
// used for recursive lock is above the older one.
|
||||
__ cmpd(CCR0, Rcurrent_obj, Robj_to_lock);
|
||||
__ beq(CCR0, Lexit); // recursive locking
|
||||
|
||||
__ cmpdi(CCR0, Rcurrent_obj, 0);
|
||||
__ bne(CCR0, LnotFree);
|
||||
__ mr(Rfree_slot, Rcurrent_monitor); // remember free slot closest to the bottom
|
||||
__ bind(LnotFree);
|
||||
|
||||
__ addi(Rcurrent_monitor, Rcurrent_monitor, frame::interpreter_frame_monitor_size_in_bytes());
|
||||
__ cmpld(CCR0, Rcurrent_monitor, Rbot);
|
||||
__ bne(CCR0, Lloop);
|
||||
__ bind(Lexit);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Check if we found a free slot.
|
||||
__ bind(Lexit);
|
||||
|
||||
__ addi(Rcurrent_monitor, Rcurrent_obj_addr, -(frame::interpreter_frame_monitor_size() * wordSize) - BasicObjectLock::obj_offset_in_bytes());
|
||||
__ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, - frame::interpreter_frame_monitor_size() * wordSize);
|
||||
__ b(Lfound);
|
||||
__ cmpdi(CCR0, Rfree_slot, 0);
|
||||
__ bne(CCR0, Lfound);
|
||||
|
||||
// We didn't find a free BasicObjLock => allocate one.
|
||||
__ align(32, 12);
|
||||
__ bind(Lallocate_new);
|
||||
__ add_monitor_to_stack(false, Rscratch1, Rscratch2);
|
||||
__ mr(Rcurrent_monitor, R26_monitor);
|
||||
__ addi(Rcurrent_obj_addr, R26_monitor, BasicObjectLock::obj_offset_in_bytes());
|
||||
__ mr(Rfree_slot, R26_monitor);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// We now have a slot to lock.
|
||||
__ bind(Lfound);
|
||||
|
||||
// Increment bcp to point to the next bytecode, so exception handling for async. exceptions work correctly.
|
||||
// The object has already been poped from the stack, so the expression stack looks correct.
|
||||
// The object has already been popped from the stack, so the expression stack looks correct.
|
||||
__ addi(R14_bcp, R14_bcp, 1);
|
||||
|
||||
__ std(Robj_to_lock, 0, Rcurrent_obj_addr);
|
||||
__ lock_object(Rcurrent_monitor, Robj_to_lock);
|
||||
__ std(Robj_to_lock, BasicObjectLock::obj_offset_in_bytes(), Rfree_slot);
|
||||
__ lock_object(Rfree_slot, Robj_to_lock);
|
||||
|
||||
// Check if there's enough space on the stack for the monitors after locking.
|
||||
// This emits a single store.
|
||||
@@ -4142,46 +4130,40 @@ void TemplateTable::monitorexit() {
|
||||
transition(atos, vtos);
|
||||
__ verify_oop(R17_tos);
|
||||
|
||||
Register Rcurrent_monitor = R11_scratch1,
|
||||
Rcurrent_obj = R12_scratch2,
|
||||
Register Rcurrent_monitor = R3_ARG1,
|
||||
Rcurrent_obj = R4_ARG2,
|
||||
Robj_to_lock = R17_tos,
|
||||
Rcurrent_obj_addr = R3_ARG1,
|
||||
Rlimit = R4_ARG2;
|
||||
Rscratch = R11_scratch1,
|
||||
Rbot = R12_scratch2;
|
||||
|
||||
Label Lfound, Lillegal_monitor_state;
|
||||
|
||||
// Check corner case: unbalanced monitorEnter / Exit.
|
||||
__ ld(Rlimit, 0, R1_SP);
|
||||
__ addi(Rlimit, Rlimit, - (frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes())); // Monitor base
|
||||
__ ld(Rscratch, _abi0(callers_sp), R1_SP); // load FP
|
||||
|
||||
// Set up search loop - start with topmost monitor.
|
||||
__ mr(Rcurrent_monitor, R26_monitor);
|
||||
__ addi(Rbot, Rscratch, -frame::ijava_state_size);
|
||||
|
||||
// Null pointer check.
|
||||
__ null_check_throw(Robj_to_lock, -1, R11_scratch1);
|
||||
__ null_check_throw(Robj_to_lock, -1, Rscratch);
|
||||
|
||||
__ cmpld(CCR0, R26_monitor, Rlimit);
|
||||
__ bgt(CCR0, Lillegal_monitor_state);
|
||||
// Check corner case: unbalanced monitorEnter / Exit.
|
||||
__ cmpld(CCR0, Rcurrent_monitor, Rbot);
|
||||
__ beq(CCR0, Lillegal_monitor_state);
|
||||
|
||||
// Find the corresponding slot in the monitors stack section.
|
||||
{
|
||||
Label Lloop;
|
||||
|
||||
// Start with topmost monitor.
|
||||
__ addi(Rcurrent_obj_addr, R26_monitor, BasicObjectLock::obj_offset_in_bytes());
|
||||
__ addi(Rlimit, Rlimit, BasicObjectLock::obj_offset_in_bytes());
|
||||
__ ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
|
||||
__ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize);
|
||||
|
||||
__ bind(Lloop);
|
||||
__ ld(Rcurrent_obj, BasicObjectLock::obj_offset_in_bytes(), Rcurrent_monitor);
|
||||
// Is this entry for same obj?
|
||||
__ cmpd(CCR0, Rcurrent_obj, Robj_to_lock);
|
||||
__ beq(CCR0, Lfound);
|
||||
|
||||
// Check if last allocated BasicLockObj reached.
|
||||
|
||||
__ ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
|
||||
__ cmpld(CCR0, Rcurrent_obj_addr, Rlimit);
|
||||
__ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize);
|
||||
|
||||
// Next iteration if unchecked BasicObjectLocks exist on the stack.
|
||||
__ ble(CCR0, Lloop);
|
||||
__ addi(Rcurrent_monitor, Rcurrent_monitor, frame::interpreter_frame_monitor_size_in_bytes());
|
||||
__ cmpld(CCR0, Rcurrent_monitor, Rbot);
|
||||
__ bne(CCR0, Lloop);
|
||||
}
|
||||
|
||||
// Fell through without finding the basic obj lock => throw up!
|
||||
@@ -4191,8 +4173,6 @@ void TemplateTable::monitorexit() {
|
||||
|
||||
__ align(32, 12);
|
||||
__ bind(Lfound);
|
||||
__ addi(Rcurrent_monitor, Rcurrent_obj_addr,
|
||||
-(frame::interpreter_frame_monitor_size() * wordSize) - BasicObjectLock::obj_offset_in_bytes());
|
||||
__ unlock_object(Rcurrent_monitor);
|
||||
}
|
||||
|
||||
|
||||
@@ -308,6 +308,22 @@ public:
|
||||
rdy = 0b111, // in instruction's rm field, selects dynamic rounding mode.In Rounding Mode register, Invalid.
|
||||
};
|
||||
|
||||
// handle unaligned access
|
||||
static inline uint16_t ld_c_instr(address addr) {
|
||||
return Bytes::get_native_u2(addr);
|
||||
}
|
||||
static inline void sd_c_instr(address addr, uint16_t c_instr) {
|
||||
Bytes::put_native_u2(addr, c_instr);
|
||||
}
|
||||
|
||||
// handle unaligned access
|
||||
static inline uint32_t ld_instr(address addr) {
|
||||
return Bytes::get_native_u4(addr);
|
||||
}
|
||||
static inline void sd_instr(address addr, uint32_t instr) {
|
||||
Bytes::put_native_u4(addr, instr);
|
||||
}
|
||||
|
||||
static inline uint32_t extract(uint32_t val, unsigned msb, unsigned lsb) {
|
||||
assert_cond(msb >= lsb && msb <= 31);
|
||||
unsigned nbits = msb - lsb + 1;
|
||||
@@ -332,10 +348,10 @@ public:
|
||||
unsigned mask = (1U << nbits) - 1;
|
||||
val <<= lsb;
|
||||
mask <<= lsb;
|
||||
unsigned target = *(unsigned *)a;
|
||||
unsigned target = ld_instr(a);
|
||||
target &= ~mask;
|
||||
target |= val;
|
||||
*(unsigned *)a = target;
|
||||
sd_instr(a, target);
|
||||
}
|
||||
|
||||
static void patch(address a, unsigned bit, unsigned val) {
|
||||
@@ -1877,10 +1893,10 @@ public:
|
||||
uint16_t mask = (1U << nbits) - 1;
|
||||
val <<= lsb;
|
||||
mask <<= lsb;
|
||||
uint16_t target = *(uint16_t *)a;
|
||||
uint16_t target = ld_c_instr(a);
|
||||
target &= ~mask;
|
||||
target |= val;
|
||||
*(uint16_t *)a = target;
|
||||
sd_c_instr(a, target);
|
||||
}
|
||||
|
||||
static void c_patch(address a, unsigned bit, uint16_t val) {
|
||||
|
||||
@@ -804,7 +804,7 @@ void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
|
||||
}
|
||||
|
||||
void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {
|
||||
fatal("vectorizedMismatch intrinsic is not implemented on this platform");
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f
|
||||
|
||||
@@ -489,7 +489,9 @@ void C2_MacroAssembler::string_indexof(Register haystack, Register needle,
|
||||
}
|
||||
bne(tmp3, skipch, BMSKIP); // if not equal, skipch is bad char
|
||||
add(result, haystack, isLL ? nlen_tmp : ch2);
|
||||
ld(ch2, Address(result)); // load 8 bytes from source string
|
||||
// load 8 bytes from source string
|
||||
// if isLL is false then read granularity can be 2
|
||||
load_long_misaligned(ch2, Address(result), ch1, isLL ? 1 : 2); // can use ch1 as temp register here as it will be trashed by next mv anyway
|
||||
mv(ch1, tmp6);
|
||||
if (isLL) {
|
||||
j(BMLOOPSTR1_AFTER_LOAD);
|
||||
@@ -672,10 +674,30 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne
|
||||
slli(tmp3, result_tmp, haystack_chr_shift); // result as tmp
|
||||
add(haystack, haystack, tmp3);
|
||||
neg(hlen_neg, tmp3);
|
||||
if (AvoidUnalignedAccesses) {
|
||||
// preload first value, then we will read by 1 character per loop, instead of four
|
||||
// just shifting previous ch2 right by size of character in bits
|
||||
add(tmp3, haystack, hlen_neg);
|
||||
(this->*load_4chr)(ch2, Address(tmp3), noreg);
|
||||
if (isLL) {
|
||||
// need to erase 1 most significant byte in 32-bit value of ch2
|
||||
slli(ch2, ch2, 40);
|
||||
srli(ch2, ch2, 32);
|
||||
} else {
|
||||
slli(ch2, ch2, 16); // 2 most significant bytes will be erased by this operation
|
||||
}
|
||||
}
|
||||
|
||||
bind(CH1_LOOP);
|
||||
add(ch2, haystack, hlen_neg);
|
||||
(this->*load_4chr)(ch2, Address(ch2), noreg);
|
||||
add(tmp3, haystack, hlen_neg);
|
||||
if (AvoidUnalignedAccesses) {
|
||||
srli(ch2, ch2, isLL ? 8 : 16);
|
||||
(this->*haystack_load_1chr)(tmp3, Address(tmp3, isLL ? 3 : 6), noreg);
|
||||
slli(tmp3, tmp3, isLL ? 24 : 48);
|
||||
add(ch2, ch2, tmp3);
|
||||
} else {
|
||||
(this->*load_4chr)(ch2, Address(tmp3), noreg);
|
||||
}
|
||||
beq(ch1, ch2, MATCH);
|
||||
add(hlen_neg, hlen_neg, haystack_chr_size);
|
||||
blez(hlen_neg, CH1_LOOP);
|
||||
@@ -693,10 +715,23 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne
|
||||
slli(tmp3, result_tmp, haystack_chr_shift);
|
||||
add(haystack, haystack, tmp3);
|
||||
neg(hlen_neg, tmp3);
|
||||
|
||||
if (AvoidUnalignedAccesses) {
|
||||
// preload first value, then we will read by 1 character per loop, instead of two
|
||||
// just shifting previous ch2 right by size of character in bits
|
||||
add(tmp3, haystack, hlen_neg);
|
||||
(this->*haystack_load_1chr)(ch2, Address(tmp3), noreg);
|
||||
slli(ch2, ch2, isLL ? 8 : 16);
|
||||
}
|
||||
bind(CH1_LOOP);
|
||||
add(tmp3, haystack, hlen_neg);
|
||||
(this->*load_2chr)(ch2, Address(tmp3), noreg);
|
||||
if (AvoidUnalignedAccesses) {
|
||||
srli(ch2, ch2, isLL ? 8 : 16);
|
||||
(this->*haystack_load_1chr)(tmp3, Address(tmp3, isLL ? 1 : 2), noreg);
|
||||
slli(tmp3, tmp3, isLL ? 8 : 16);
|
||||
add(ch2, ch2, tmp3);
|
||||
} else {
|
||||
(this->*load_2chr)(ch2, Address(tmp3), noreg);
|
||||
}
|
||||
beq(ch1, ch2, MATCH);
|
||||
add(hlen_neg, hlen_neg, haystack_chr_size);
|
||||
blez(hlen_neg, CH1_LOOP);
|
||||
@@ -720,7 +755,14 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne
|
||||
|
||||
bind(FIRST_LOOP);
|
||||
add(ch2, haystack, hlen_neg);
|
||||
(this->*load_2chr)(ch2, Address(ch2), noreg);
|
||||
if (AvoidUnalignedAccesses) {
|
||||
(this->*haystack_load_1chr)(tmp2, Address(ch2, isLL ? 1 : 2), noreg); // we need a temp register, we can safely use hlen_tmp here, which is a synonym for tmp2
|
||||
(this->*haystack_load_1chr)(ch2, Address(ch2), noreg);
|
||||
slli(tmp2, tmp2, isLL ? 8 : 16);
|
||||
add(ch2, ch2, tmp2);
|
||||
} else {
|
||||
(this->*load_2chr)(ch2, Address(ch2), noreg);
|
||||
}
|
||||
beq(first, ch2, STR1_LOOP);
|
||||
|
||||
bind(STR2_NEXT);
|
||||
@@ -744,10 +786,7 @@ void C2_MacroAssembler::string_indexof_linearscan(Register haystack, Register ne
|
||||
bind(DO1);
|
||||
(this->*needle_load_1chr)(ch1, Address(needle), noreg);
|
||||
sub(result_tmp, haystack_len, 1);
|
||||
mv(tmp3, result_tmp);
|
||||
if (haystack_chr_shift) {
|
||||
slli(tmp3, result_tmp, haystack_chr_shift);
|
||||
}
|
||||
slli(tmp3, result_tmp, haystack_chr_shift);
|
||||
add(haystack, haystack, tmp3);
|
||||
neg(hlen_neg, tmp3);
|
||||
|
||||
@@ -822,9 +861,10 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2,
|
||||
// load first parts of strings and finish initialization while loading
|
||||
{
|
||||
if (str1_isL == str2_isL) { // LL or UU
|
||||
// check if str1 and str2 is same pointer
|
||||
beq(str1, str2, DONE);
|
||||
// load 8 bytes once to compare
|
||||
ld(tmp1, Address(str1));
|
||||
beq(str1, str2, DONE);
|
||||
ld(tmp2, Address(str2));
|
||||
mv(t0, STUB_THRESHOLD);
|
||||
bge(cnt2, t0, STUB);
|
||||
@@ -867,9 +907,8 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2,
|
||||
addi(cnt1, cnt1, 8);
|
||||
}
|
||||
addi(cnt2, cnt2, isUL ? 4 : 8);
|
||||
bne(tmp1, tmp2, DIFFERENCE);
|
||||
bgez(cnt2, TAIL);
|
||||
xorr(tmp3, tmp1, tmp2);
|
||||
bnez(tmp3, DIFFERENCE);
|
||||
|
||||
// main loop
|
||||
bind(NEXT_WORD);
|
||||
@@ -898,38 +937,30 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2,
|
||||
addi(cnt1, cnt1, 8);
|
||||
addi(cnt2, cnt2, 4);
|
||||
}
|
||||
bgez(cnt2, TAIL);
|
||||
|
||||
xorr(tmp3, tmp1, tmp2);
|
||||
beqz(tmp3, NEXT_WORD);
|
||||
j(DIFFERENCE);
|
||||
bne(tmp1, tmp2, DIFFERENCE);
|
||||
bltz(cnt2, NEXT_WORD);
|
||||
bind(TAIL);
|
||||
xorr(tmp3, tmp1, tmp2);
|
||||
bnez(tmp3, DIFFERENCE);
|
||||
// Last longword. In the case where length == 4 we compare the
|
||||
// same longword twice, but that's still faster than another
|
||||
// conditional branch.
|
||||
if (str1_isL == str2_isL) { // LL or UU
|
||||
ld(tmp1, Address(str1));
|
||||
ld(tmp2, Address(str2));
|
||||
load_long_misaligned(tmp1, Address(str1), tmp3, isLL ? 1 : 2);
|
||||
load_long_misaligned(tmp2, Address(str2), tmp3, isLL ? 1 : 2);
|
||||
} else if (isLU) { // LU case
|
||||
lwu(tmp1, Address(str1));
|
||||
ld(tmp2, Address(str2));
|
||||
load_int_misaligned(tmp1, Address(str1), tmp3, false);
|
||||
load_long_misaligned(tmp2, Address(str2), tmp3, 2);
|
||||
inflate_lo32(tmp3, tmp1);
|
||||
mv(tmp1, tmp3);
|
||||
} else { // UL case
|
||||
lwu(tmp2, Address(str2));
|
||||
ld(tmp1, Address(str1));
|
||||
load_int_misaligned(tmp2, Address(str2), tmp3, false);
|
||||
load_long_misaligned(tmp1, Address(str1), tmp3, 2);
|
||||
inflate_lo32(tmp3, tmp2);
|
||||
mv(tmp2, tmp3);
|
||||
}
|
||||
bind(TAIL_CHECK);
|
||||
xorr(tmp3, tmp1, tmp2);
|
||||
beqz(tmp3, DONE);
|
||||
beq(tmp1, tmp2, DONE);
|
||||
|
||||
// Find the first different characters in the longwords and
|
||||
// compute their difference.
|
||||
bind(DIFFERENCE);
|
||||
xorr(tmp3, tmp1, tmp2);
|
||||
ctzc_bit(result, tmp3, isLL); // count zero from lsb to msb
|
||||
srl(tmp1, tmp1, result);
|
||||
srl(tmp2, tmp2, result);
|
||||
@@ -1099,8 +1130,10 @@ void C2_MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
|
||||
// and a2 and the length in cnt1.
|
||||
// elem_size is the element size in bytes: either 1 or 2.
|
||||
// There are two implementations. For arrays >= 8 bytes, all
|
||||
// comparisons (including the final one, which may overlap) are
|
||||
// performed 8 bytes at a time. For strings < 8 bytes, we compare a
|
||||
// comparisons (for hw supporting unaligned access: including the final one,
|
||||
// which may overlap) are performed 8 bytes at a time.
|
||||
// For strings < 8 bytes (and for tails of long strings when
|
||||
// AvoidUnalignedAccesses is true), we compare a
|
||||
// halfword, then a short, and then a byte.
|
||||
|
||||
void C2_MacroAssembler::string_equals(Register a1, Register a2,
|
||||
@@ -1111,10 +1144,11 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2,
|
||||
Register tmp2 = t1;
|
||||
|
||||
assert(elem_size == 1 || elem_size == 2, "must be 2 or 1 byte");
|
||||
assert_different_registers(a1, a2, result, cnt1, t0, t1);
|
||||
assert_different_registers(a1, a2, result, cnt1, tmp1, tmp2);
|
||||
|
||||
BLOCK_COMMENT("string_equals {");
|
||||
|
||||
beqz(cnt1, SAME);
|
||||
mv(result, false);
|
||||
|
||||
// Check for short strings, i.e. smaller than wordSize.
|
||||
@@ -1129,26 +1163,31 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2,
|
||||
add(a2, a2, wordSize);
|
||||
sub(cnt1, cnt1, wordSize);
|
||||
bne(tmp1, tmp2, DONE);
|
||||
} bgtz(cnt1, NEXT_WORD);
|
||||
} bgez(cnt1, NEXT_WORD);
|
||||
|
||||
// Last longword. In the case where length == 4 we compare the
|
||||
// same longword twice, but that's still faster than another
|
||||
// conditional branch.
|
||||
// cnt1 could be 0, -1, -2, -3, -4 for chars; -4 only happens when
|
||||
// length == 4.
|
||||
add(tmp1, a1, cnt1);
|
||||
ld(tmp1, Address(tmp1, 0));
|
||||
add(tmp2, a2, cnt1);
|
||||
ld(tmp2, Address(tmp2, 0));
|
||||
bne(tmp1, tmp2, DONE);
|
||||
j(SAME);
|
||||
if (!AvoidUnalignedAccesses) {
|
||||
// Last longword. In the case where length == 4 we compare the
|
||||
// same longword twice, but that's still faster than another
|
||||
// conditional branch.
|
||||
// cnt1 could be 0, -1, -2, -3, -4 for chars; -4 only happens when
|
||||
// length == 4.
|
||||
add(tmp1, a1, cnt1);
|
||||
ld(tmp1, Address(tmp1, 0));
|
||||
add(tmp2, a2, cnt1);
|
||||
ld(tmp2, Address(tmp2, 0));
|
||||
bne(tmp1, tmp2, DONE);
|
||||
j(SAME);
|
||||
} else {
|
||||
add(tmp1, cnt1, wordSize);
|
||||
beqz(tmp1, SAME);
|
||||
}
|
||||
|
||||
bind(SHORT);
|
||||
Label TAIL03, TAIL01;
|
||||
|
||||
// 0-7 bytes left.
|
||||
test_bit(t0, cnt1, 2);
|
||||
beqz(t0, TAIL03);
|
||||
test_bit(tmp1, cnt1, 2);
|
||||
beqz(tmp1, TAIL03);
|
||||
{
|
||||
lwu(tmp1, Address(a1, 0));
|
||||
add(a1, a1, 4);
|
||||
@@ -1159,8 +1198,8 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2,
|
||||
|
||||
bind(TAIL03);
|
||||
// 0-3 bytes left.
|
||||
test_bit(t0, cnt1, 1);
|
||||
beqz(t0, TAIL01);
|
||||
test_bit(tmp1, cnt1, 1);
|
||||
beqz(tmp1, TAIL01);
|
||||
{
|
||||
lhu(tmp1, Address(a1, 0));
|
||||
add(a1, a1, 2);
|
||||
@@ -1172,8 +1211,8 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2,
|
||||
bind(TAIL01);
|
||||
if (elem_size == 1) { // Only needed when comparing 1-byte elements
|
||||
// 0-1 bytes left.
|
||||
test_bit(t0, cnt1, 0);
|
||||
beqz(t0, SAME);
|
||||
test_bit(tmp1, cnt1, 0);
|
||||
beqz(tmp1, SAME);
|
||||
{
|
||||
lbu(tmp1, Address(a1, 0));
|
||||
lbu(tmp2, Address(a2, 0));
|
||||
|
||||
@@ -84,11 +84,11 @@ static const struct CheckInsn barrierInsn[] = {
|
||||
// BarrierSetAssembler::nmethod_entry_barrier. The matching ignores the specific
|
||||
// register numbers and immediate values in the encoding.
|
||||
void NativeNMethodBarrier::verify() const {
|
||||
intptr_t addr = (intptr_t) instruction_address();
|
||||
address addr = instruction_address();
|
||||
for(unsigned int i = 0; i < sizeof(barrierInsn)/sizeof(struct CheckInsn); i++ ) {
|
||||
uint32_t inst = *((uint32_t*) addr);
|
||||
uint32_t inst = Assembler::ld_instr(addr);
|
||||
if ((inst & barrierInsn[i].mask) != barrierInsn[i].bits) {
|
||||
tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", addr, inst);
|
||||
tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(addr), inst);
|
||||
fatal("not an %s instruction.", barrierInsn[i].name);
|
||||
}
|
||||
addr += 4;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2023, Rivos Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -25,6 +26,8 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "riscv_flush_icache.hpp"
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/icache.hpp"
|
||||
|
||||
#define __ _masm->
|
||||
@@ -33,16 +36,22 @@ static int icache_flush(address addr, int lines, int magic) {
|
||||
// To make a store to instruction memory visible to all RISC-V harts,
|
||||
// the writing hart has to execute a data FENCE before requesting that
|
||||
// all remote RISC-V harts execute a FENCE.I.
|
||||
//
|
||||
// No sush assurance is defined at the interface level of the builtin
|
||||
// method, and so we should make sure it works.
|
||||
|
||||
// We need to make sure stores happens before the I/D cache synchronization.
|
||||
__asm__ volatile("fence rw, rw" : : : "memory");
|
||||
|
||||
__builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size));
|
||||
RiscvFlushIcache::flush((uintptr_t)addr, ((uintptr_t)lines) << ICache::log2_line_size);
|
||||
|
||||
return magic;
|
||||
}
|
||||
|
||||
void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) {
|
||||
// Only riscv_flush_icache is supported as I-cache synchronization.
|
||||
// We must make sure the VM can execute such without error.
|
||||
if (!RiscvFlushIcache::test()) {
|
||||
vm_exit_during_initialization("Unable to synchronize I-cache");
|
||||
}
|
||||
|
||||
address start = (address)icache_flush;
|
||||
*flush_icache_stub = (ICache::flush_icache_stub_t)start;
|
||||
|
||||
|
||||
@@ -176,8 +176,15 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread)
|
||||
|
||||
void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) {
|
||||
assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
|
||||
lhu(reg, Address(xbcp, bcp_offset));
|
||||
revb_h(reg, reg);
|
||||
if (AvoidUnalignedAccesses && (bcp_offset % 2)) {
|
||||
lbu(t1, Address(xbcp, bcp_offset));
|
||||
lbu(reg, Address(xbcp, bcp_offset + 1));
|
||||
slli(t1, t1, 8);
|
||||
add(reg, reg, t1);
|
||||
} else {
|
||||
lhu(reg, Address(xbcp, bcp_offset));
|
||||
revb_h_h_u(reg, reg);
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::get_dispatch() {
|
||||
@@ -190,13 +197,23 @@ void InterpreterMacroAssembler::get_dispatch() {
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index,
|
||||
Register tmp,
|
||||
int bcp_offset,
|
||||
size_t index_size) {
|
||||
assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
|
||||
if (index_size == sizeof(u2)) {
|
||||
load_unsigned_short(index, Address(xbcp, bcp_offset));
|
||||
if (AvoidUnalignedAccesses) {
|
||||
assert_different_registers(index, tmp);
|
||||
load_unsigned_byte(index, Address(xbcp, bcp_offset));
|
||||
load_unsigned_byte(tmp, Address(xbcp, bcp_offset + 1));
|
||||
slli(tmp, tmp, 8);
|
||||
add(index, index, tmp);
|
||||
} else {
|
||||
load_unsigned_short(index, Address(xbcp, bcp_offset));
|
||||
}
|
||||
} else if (index_size == sizeof(u4)) {
|
||||
lwu(index, Address(xbcp, bcp_offset));
|
||||
load_int_misaligned(index, Address(xbcp, bcp_offset), tmp, false);
|
||||
|
||||
// Check if the secondary index definition is still ~x, otherwise
|
||||
// we have to change the following assembler code to calculate the
|
||||
// plain index.
|
||||
@@ -223,7 +240,8 @@ void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache,
|
||||
size_t index_size) {
|
||||
assert_different_registers(cache, index);
|
||||
assert_different_registers(cache, xcpool);
|
||||
get_cache_index_at_bcp(index, bcp_offset, index_size);
|
||||
// register "cache" is trashed in next shadd, so lets use it as a temporary register
|
||||
get_cache_index_at_bcp(index, cache, bcp_offset, index_size);
|
||||
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
|
||||
// Convert from field index to ConstantPoolCacheEntry
|
||||
// riscv already has the cache in xcpool so there is no need to
|
||||
@@ -260,7 +278,8 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
|
||||
int bcp_offset,
|
||||
size_t index_size) {
|
||||
assert_different_registers(cache, tmp);
|
||||
get_cache_index_at_bcp(tmp, bcp_offset, index_size);
|
||||
// register "cache" is trashed in next ld, so lets use it as a temporary register
|
||||
get_cache_index_at_bcp(tmp, cache, bcp_offset, index_size);
|
||||
assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below");
|
||||
// Convert from field index to ConstantPoolCacheEntry index
|
||||
// and from word offset to byte offset
|
||||
|
||||
@@ -113,7 +113,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
void get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset, size_t index_size = sizeof(u2));
|
||||
void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
|
||||
void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
|
||||
void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
|
||||
void get_cache_index_at_bcp(Register index, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
|
||||
void get_method_counters(Register method, Register mcs, Label& skip);
|
||||
|
||||
// Load cpool->resolved_references(index).
|
||||
|
||||
@@ -1350,7 +1350,7 @@ static int patch_imm_in_li32(address branch, int32_t target) {
|
||||
static long get_offset_of_jal(address insn_addr) {
|
||||
assert_cond(insn_addr != NULL);
|
||||
long offset = 0;
|
||||
unsigned insn = *(unsigned*)insn_addr;
|
||||
unsigned insn = Assembler::ld_instr(insn_addr);
|
||||
long val = (long)Assembler::sextract(insn, 31, 12);
|
||||
offset |= ((val >> 19) & 0x1) << 20;
|
||||
offset |= (val & 0xff) << 12;
|
||||
@@ -1363,7 +1363,7 @@ static long get_offset_of_jal(address insn_addr) {
|
||||
static long get_offset_of_conditional_branch(address insn_addr) {
|
||||
long offset = 0;
|
||||
assert_cond(insn_addr != NULL);
|
||||
unsigned insn = *(unsigned*)insn_addr;
|
||||
unsigned insn = Assembler::ld_instr(insn_addr);
|
||||
offset = (long)Assembler::sextract(insn, 31, 31);
|
||||
offset = (offset << 12) | (((long)(Assembler::sextract(insn, 7, 7) & 0x1)) << 11);
|
||||
offset = offset | (((long)(Assembler::sextract(insn, 30, 25) & 0x3f)) << 5);
|
||||
@@ -1375,35 +1375,35 @@ static long get_offset_of_conditional_branch(address insn_addr) {
|
||||
static long get_offset_of_pc_relative(address insn_addr) {
|
||||
long offset = 0;
|
||||
assert_cond(insn_addr != NULL);
|
||||
offset = ((long)(Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12))) << 12; // Auipc.
|
||||
offset += ((long)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)); // Addi/Jalr/Load.
|
||||
offset = ((long)(Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12))) << 12; // Auipc.
|
||||
offset += ((long)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)); // Addi/Jalr/Load.
|
||||
offset = (offset << 32) >> 32;
|
||||
return offset;
|
||||
}
|
||||
|
||||
static address get_target_of_movptr(address insn_addr) {
|
||||
assert_cond(insn_addr != NULL);
|
||||
intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 29; // Lui.
|
||||
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)) << 17; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[3], 31, 20)) << 6; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[5], 31, 20)); // Addi/Jalr/Load.
|
||||
intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 29; // Lui.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)) << 17; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 12), 31, 20)) << 6; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 20), 31, 20)); // Addi/Jalr/Load.
|
||||
return (address) target_address;
|
||||
}
|
||||
|
||||
static address get_target_of_li64(address insn_addr) {
|
||||
assert_cond(insn_addr != NULL);
|
||||
intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 44; // Lui.
|
||||
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)) << 32; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[3], 31, 20)) << 20; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[5], 31, 20)) << 8; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[7], 31, 20)); // Addi.
|
||||
intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 44; // Lui.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)) << 32; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 12), 31, 20)) << 20; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 20), 31, 20)) << 8; // Addi.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 28), 31, 20)); // Addi.
|
||||
return (address)target_address;
|
||||
}
|
||||
|
||||
static address get_target_of_li32(address insn_addr) {
|
||||
assert_cond(insn_addr != NULL);
|
||||
intptr_t target_address = (((int64_t)Assembler::sextract(((unsigned*)insn_addr)[0], 31, 12)) & 0xfffff) << 12; // Lui.
|
||||
target_address += ((int64_t)Assembler::sextract(((unsigned*)insn_addr)[1], 31, 20)); // Addiw.
|
||||
intptr_t target_address = (((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr), 31, 12)) & 0xfffff) << 12; // Lui.
|
||||
target_address += ((int64_t)Assembler::sextract(Assembler::ld_instr(insn_addr + 4), 31, 20)); // Addiw.
|
||||
return (address)target_address;
|
||||
}
|
||||
|
||||
@@ -1428,7 +1428,7 @@ int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
|
||||
} else {
|
||||
#ifdef ASSERT
|
||||
tty->print_cr("pd_patch_instruction_size: instruction 0x%x at " INTPTR_FORMAT " could not be patched!\n",
|
||||
*(unsigned*)branch, p2i(branch));
|
||||
Assembler::ld_instr(branch), p2i(branch));
|
||||
Disassembler::decode(branch - 16, branch + 16);
|
||||
#endif
|
||||
ShouldNotReachHere();
|
||||
@@ -1571,6 +1571,28 @@ void MacroAssembler::xorrw(Register Rd, Register Rs1, Register Rs2) {
|
||||
sign_extend(Rd, Rd, 32);
|
||||
}
|
||||
|
||||
// Rd = Rs1 & (~Rd2)
|
||||
void MacroAssembler::andn(Register Rd, Register Rs1, Register Rs2) {
|
||||
if (UseZbb) {
|
||||
Assembler::andn(Rd, Rs1, Rs2);
|
||||
return;
|
||||
}
|
||||
|
||||
notr(Rd, Rs2);
|
||||
andr(Rd, Rs1, Rd);
|
||||
}
|
||||
|
||||
// Rd = Rs1 | (~Rd2)
|
||||
void MacroAssembler::orn(Register Rd, Register Rs1, Register Rs2) {
|
||||
if (UseZbb) {
|
||||
Assembler::orn(Rd, Rs1, Rs2);
|
||||
return;
|
||||
}
|
||||
|
||||
notr(Rd, Rs2);
|
||||
orr(Rd, Rs1, Rd);
|
||||
}
|
||||
|
||||
// Note: load_unsigned_short used to be called load_unsigned_word.
|
||||
int MacroAssembler::load_unsigned_short(Register dst, Address src) {
|
||||
int off = offset();
|
||||
@@ -1616,6 +1638,114 @@ void MacroAssembler::store_sized_value(Address dst, Register src, size_t size_in
|
||||
}
|
||||
}
|
||||
|
||||
// granularity is 1 OR 2 bytes per load. dst and src.base() allowed to be the same register
|
||||
void MacroAssembler::load_short_misaligned(Register dst, Address src, Register tmp, bool is_signed, int granularity) {
|
||||
if (granularity != 1 && granularity != 2) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
if (AvoidUnalignedAccesses && (granularity != 2)) {
|
||||
assert_different_registers(dst, tmp);
|
||||
assert_different_registers(tmp, src.base());
|
||||
is_signed ? lb(tmp, Address(src.base(), src.offset() + 1)) : lbu(tmp, Address(src.base(), src.offset() + 1));
|
||||
slli(tmp, tmp, 8);
|
||||
lbu(dst, src);
|
||||
add(dst, dst, tmp);
|
||||
} else {
|
||||
is_signed ? lh(dst, src) : lhu(dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
// granularity is 1, 2 OR 4 bytes per load, if granularity 2 or 4 then dst and src.base() allowed to be the same register
|
||||
void MacroAssembler::load_int_misaligned(Register dst, Address src, Register tmp, bool is_signed, int granularity) {
|
||||
if (AvoidUnalignedAccesses && (granularity != 4)) {
|
||||
switch(granularity) {
|
||||
case 1:
|
||||
assert_different_registers(dst, tmp, src.base());
|
||||
lbu(dst, src);
|
||||
lbu(tmp, Address(src.base(), src.offset() + 1));
|
||||
slli(tmp, tmp, 8);
|
||||
add(dst, dst, tmp);
|
||||
lbu(tmp, Address(src.base(), src.offset() + 2));
|
||||
slli(tmp, tmp, 16);
|
||||
add(dst, dst, tmp);
|
||||
is_signed ? lb(tmp, Address(src.base(), src.offset() + 3)) : lbu(tmp, Address(src.base(), src.offset() + 3));
|
||||
slli(tmp, tmp, 24);
|
||||
add(dst, dst, tmp);
|
||||
break;
|
||||
case 2:
|
||||
assert_different_registers(dst, tmp);
|
||||
assert_different_registers(tmp, src.base());
|
||||
is_signed ? lh(tmp, Address(src.base(), src.offset() + 2)) : lhu(tmp, Address(src.base(), src.offset() + 2));
|
||||
slli(tmp, tmp, 16);
|
||||
lhu(dst, src);
|
||||
add(dst, dst, tmp);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
} else {
|
||||
is_signed ? lw(dst, src) : lwu(dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
// granularity is 1, 2, 4 or 8 bytes per load, if granularity 4 or 8 then dst and src.base() allowed to be same register
|
||||
void MacroAssembler::load_long_misaligned(Register dst, Address src, Register tmp, int granularity) {
|
||||
if (AvoidUnalignedAccesses && (granularity != 8)) {
|
||||
switch(granularity){
|
||||
case 1:
|
||||
assert_different_registers(dst, tmp, src.base());
|
||||
lbu(dst, src);
|
||||
lbu(tmp, Address(src.base(), src.offset() + 1));
|
||||
slli(tmp, tmp, 8);
|
||||
add(dst, dst, tmp);
|
||||
lbu(tmp, Address(src.base(), src.offset() + 2));
|
||||
slli(tmp, tmp, 16);
|
||||
add(dst, dst, tmp);
|
||||
lbu(tmp, Address(src.base(), src.offset() + 3));
|
||||
slli(tmp, tmp, 24);
|
||||
add(dst, dst, tmp);
|
||||
lbu(tmp, Address(src.base(), src.offset() + 4));
|
||||
slli(tmp, tmp, 32);
|
||||
add(dst, dst, tmp);
|
||||
lbu(tmp, Address(src.base(), src.offset() + 5));
|
||||
slli(tmp, tmp, 40);
|
||||
add(dst, dst, tmp);
|
||||
lbu(tmp, Address(src.base(), src.offset() + 6));
|
||||
slli(tmp, tmp, 48);
|
||||
add(dst, dst, tmp);
|
||||
lbu(tmp, Address(src.base(), src.offset() + 7));
|
||||
slli(tmp, tmp, 56);
|
||||
add(dst, dst, tmp);
|
||||
break;
|
||||
case 2:
|
||||
assert_different_registers(dst, tmp, src.base());
|
||||
lhu(dst, src);
|
||||
lhu(tmp, Address(src.base(), src.offset() + 2));
|
||||
slli(tmp, tmp, 16);
|
||||
add(dst, dst, tmp);
|
||||
lhu(tmp, Address(src.base(), src.offset() + 4));
|
||||
slli(tmp, tmp, 32);
|
||||
add(dst, dst, tmp);
|
||||
lhu(tmp, Address(src.base(), src.offset() + 6));
|
||||
slli(tmp, tmp, 48);
|
||||
add(dst, dst, tmp);
|
||||
break;
|
||||
case 4:
|
||||
assert_different_registers(dst, tmp);
|
||||
assert_different_registers(tmp, src.base());
|
||||
lwu(tmp, Address(src.base(), src.offset() + 4));
|
||||
slli(tmp, tmp, 32);
|
||||
lwu(dst, src);
|
||||
add(dst, dst, tmp);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
} else {
|
||||
ld(dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
// reverse bytes in halfword in lower 16 bits and sign-extend
|
||||
// Rd[15:0] = Rs[7:0] Rs[15:8] (sign-extend to 64 bits)
|
||||
void MacroAssembler::revb_h_h(Register Rd, Register Rs, Register tmp) {
|
||||
@@ -1776,6 +1906,22 @@ void MacroAssembler::ror_imm(Register dst, Register src, uint32_t shift, Registe
|
||||
orr(dst, dst, tmp);
|
||||
}
|
||||
|
||||
// rotate left with shift bits, 32-bit version
|
||||
void MacroAssembler::rolw_imm(Register dst, Register src, uint32_t shift, Register tmp) {
|
||||
if (UseZbb) {
|
||||
// no roliw available
|
||||
roriw(dst, src, 32 - shift);
|
||||
return;
|
||||
}
|
||||
|
||||
assert_different_registers(dst, tmp);
|
||||
assert_different_registers(src, tmp);
|
||||
assert(shift < 32, "shift amount must be < 32");
|
||||
srliw(tmp, src, 32 - shift);
|
||||
slliw(dst, src, shift);
|
||||
orr(dst, dst, tmp);
|
||||
}
|
||||
|
||||
void MacroAssembler::andi(Register Rd, Register Rn, int64_t imm, Register tmp) {
|
||||
if (is_simm12(imm)) {
|
||||
and_imm12(Rd, Rn, imm);
|
||||
@@ -3985,18 +4131,17 @@ void MacroAssembler::ctzc_bit(Register Rd, Register Rs, bool isLL, Register tmp1
|
||||
void MacroAssembler::inflate_lo32(Register Rd, Register Rs, Register tmp1, Register tmp2) {
|
||||
assert_different_registers(Rd, Rs, tmp1, tmp2);
|
||||
|
||||
mv(tmp1, 0xFF);
|
||||
mv(Rd, zr);
|
||||
for (int i = 0; i <= 3; i++) {
|
||||
mv(tmp1, 0xFF000000); // first byte mask at lower word
|
||||
andr(Rd, Rs, tmp1);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
slli(Rd, Rd, wordSize);
|
||||
srli(tmp1, tmp1, wordSize);
|
||||
andr(tmp2, Rs, tmp1);
|
||||
if (i) {
|
||||
slli(tmp2, tmp2, i * 8);
|
||||
}
|
||||
orr(Rd, Rd, tmp2);
|
||||
if (i != 3) {
|
||||
slli(tmp1, tmp1, 8);
|
||||
}
|
||||
}
|
||||
slli(Rd, Rd, wordSize);
|
||||
andi(tmp2, Rs, 0xFF); // last byte mask at lower word
|
||||
orr(Rd, Rd, tmp2);
|
||||
}
|
||||
|
||||
// This instruction reads adjacent 4 bytes from the upper half of source register,
|
||||
@@ -4005,17 +4150,8 @@ void MacroAssembler::inflate_lo32(Register Rd, Register Rs, Register tmp1, Regis
|
||||
// Rd: 00A700A600A500A4
|
||||
void MacroAssembler::inflate_hi32(Register Rd, Register Rs, Register tmp1, Register tmp2) {
|
||||
assert_different_registers(Rd, Rs, tmp1, tmp2);
|
||||
|
||||
mv(tmp1, 0xFF00000000);
|
||||
mv(Rd, zr);
|
||||
for (int i = 0; i <= 3; i++) {
|
||||
andr(tmp2, Rs, tmp1);
|
||||
orr(Rd, Rd, tmp2);
|
||||
srli(Rd, Rd, 8);
|
||||
if (i != 3) {
|
||||
slli(tmp1, tmp1, 8);
|
||||
}
|
||||
}
|
||||
srli(Rs, Rs, 32); // only upper 32 bits are needed
|
||||
inflate_lo32(Rd, Rs, tmp1, tmp2);
|
||||
}
|
||||
|
||||
// The size of the blocks erased by the zero_blocks stub. We must
|
||||
@@ -4382,11 +4518,17 @@ void MacroAssembler::cmp_l2i(Register dst, Register src1, Register src2, Registe
|
||||
bind(done);
|
||||
}
|
||||
|
||||
void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos, Register tmp) {
|
||||
void MacroAssembler::test_bit(Register Rd, Register Rs, uint32_t bit_pos) {
|
||||
assert(bit_pos < 64, "invalid bit range");
|
||||
if (UseZbs) {
|
||||
bexti(Rd, Rs, bit_pos);
|
||||
return;
|
||||
}
|
||||
andi(Rd, Rs, 1UL << bit_pos, tmp);
|
||||
int64_t imm = (int64_t)(1UL << bit_pos);
|
||||
if (is_simm12(imm)) {
|
||||
and_imm12(Rd, Rs, imm);
|
||||
} else {
|
||||
srli(Rd, Rs, bit_pos);
|
||||
and_imm12(Rd, Rd, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,6 +407,11 @@ class MacroAssembler: public Assembler {
|
||||
void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg);
|
||||
void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg);
|
||||
|
||||
// Misaligned loads, will use the best way, according to the AvoidUnalignedAccess flag
|
||||
void load_short_misaligned(Register dst, Address src, Register tmp, bool is_signed, int granularity = 1);
|
||||
void load_int_misaligned(Register dst, Address src, Register tmp, bool is_signed, int granularity = 1);
|
||||
void load_long_misaligned(Register dst, Address src, Register tmp, int granularity = 1);
|
||||
|
||||
public:
|
||||
// Standard pseudo instructions
|
||||
inline void nop() {
|
||||
@@ -568,7 +573,9 @@ class MacroAssembler: public Assembler {
|
||||
void NAME(Register Rs1, Register Rs2, const address dest) { \
|
||||
assert_cond(dest != NULL); \
|
||||
int64_t offset = dest - pc(); \
|
||||
guarantee(is_simm13(offset) && ((offset % 2) == 0), "offset is invalid."); \
|
||||
guarantee(is_simm13(offset) && is_even(offset), \
|
||||
"offset is invalid: is_simm_13: %s offset: " INT64_FORMAT, \
|
||||
BOOL_TO_STR(is_simm13(offset)), offset); \
|
||||
Assembler::NAME(Rs1, Rs2, offset); \
|
||||
} \
|
||||
INSN_ENTRY_RELOC(void, NAME(Register Rs1, Register Rs2, address dest, relocInfo::relocType rtype)) \
|
||||
@@ -729,6 +736,10 @@ public:
|
||||
void orrw(Register Rd, Register Rs1, Register Rs2);
|
||||
void xorrw(Register Rd, Register Rs1, Register Rs2);
|
||||
|
||||
// logic with negate
|
||||
void andn(Register Rd, Register Rs1, Register Rs2);
|
||||
void orn(Register Rd, Register Rs1, Register Rs2);
|
||||
|
||||
// revb
|
||||
void revb_h_h(Register Rd, Register Rs, Register tmp = t0); // reverse bytes in halfword in lower 16 bits, sign-extend
|
||||
void revb_w_w(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); // reverse bytes in lower word, sign-extend
|
||||
@@ -740,6 +751,7 @@ public:
|
||||
void revb(Register Rd, Register Rs, Register tmp1 = t0, Register tmp2 = t1); // reverse bytes in doubleword
|
||||
|
||||
void ror_imm(Register dst, Register src, uint32_t shift, Register tmp = t0);
|
||||
void rolw_imm(Register dst, Register src, uint32_t, Register tmp = t0);
|
||||
void andi(Register Rd, Register Rn, int64_t imm, Register tmp = t0);
|
||||
void orptr(Address adr, RegisterOrConstant src, Register tmp1 = t0, Register tmp2 = t1);
|
||||
|
||||
@@ -1132,7 +1144,7 @@ public:
|
||||
void shadd(Register Rd, Register Rs1, Register Rs2, Register tmp, int shamt);
|
||||
|
||||
// test single bit in Rs, result is set to Rd
|
||||
void test_bit(Register Rd, Register Rs, uint32_t bit_pos, Register tmp = t0);
|
||||
void test_bit(Register Rd, Register Rs, uint32_t bit_pos);
|
||||
|
||||
// Here the float instructions with safe deal with some exceptions.
|
||||
// e.g. convert from NaN, +Inf, -Inf to int, float, double
|
||||
|
||||
@@ -42,27 +42,27 @@
|
||||
|
||||
Register NativeInstruction::extract_rs1(address instr) {
|
||||
assert_cond(instr != NULL);
|
||||
return as_Register(Assembler::extract(((unsigned*)instr)[0], 19, 15));
|
||||
return as_Register(Assembler::extract(Assembler::ld_instr(instr), 19, 15));
|
||||
}
|
||||
|
||||
Register NativeInstruction::extract_rs2(address instr) {
|
||||
assert_cond(instr != NULL);
|
||||
return as_Register(Assembler::extract(((unsigned*)instr)[0], 24, 20));
|
||||
return as_Register(Assembler::extract(Assembler::ld_instr(instr), 24, 20));
|
||||
}
|
||||
|
||||
Register NativeInstruction::extract_rd(address instr) {
|
||||
assert_cond(instr != NULL);
|
||||
return as_Register(Assembler::extract(((unsigned*)instr)[0], 11, 7));
|
||||
return as_Register(Assembler::extract(Assembler::ld_instr(instr), 11, 7));
|
||||
}
|
||||
|
||||
uint32_t NativeInstruction::extract_opcode(address instr) {
|
||||
assert_cond(instr != NULL);
|
||||
return Assembler::extract(((unsigned*)instr)[0], 6, 0);
|
||||
return Assembler::extract(Assembler::ld_instr(instr), 6, 0);
|
||||
}
|
||||
|
||||
uint32_t NativeInstruction::extract_funct3(address instr) {
|
||||
assert_cond(instr != NULL);
|
||||
return Assembler::extract(((unsigned*)instr)[0], 14, 12);
|
||||
return Assembler::extract(Assembler::ld_instr(instr), 14, 12);
|
||||
}
|
||||
|
||||
bool NativeInstruction::is_pc_relative_at(address instr) {
|
||||
@@ -206,7 +206,7 @@ void NativeMovConstReg::verify() {
|
||||
intptr_t NativeMovConstReg::data() const {
|
||||
address addr = MacroAssembler::target_addr_for_insn(instruction_address());
|
||||
if (maybe_cpool_ref(instruction_address())) {
|
||||
return *(intptr_t*)addr;
|
||||
return Bytes::get_native_u8(addr);
|
||||
} else {
|
||||
return (intptr_t)addr;
|
||||
}
|
||||
@@ -215,7 +215,7 @@ intptr_t NativeMovConstReg::data() const {
|
||||
void NativeMovConstReg::set_data(intptr_t x) {
|
||||
if (maybe_cpool_ref(instruction_address())) {
|
||||
address addr = MacroAssembler::target_addr_for_insn(instruction_address());
|
||||
*(intptr_t*)addr = x;
|
||||
Bytes::put_native_u8(addr, x);
|
||||
} else {
|
||||
// Store x into the instruction stream.
|
||||
MacroAssembler::pd_patch_instruction_size(instruction_address(), (address)x);
|
||||
@@ -231,11 +231,11 @@ void NativeMovConstReg::set_data(intptr_t x) {
|
||||
while (iter.next()) {
|
||||
if (iter.type() == relocInfo::oop_type) {
|
||||
oop* oop_addr = iter.oop_reloc()->oop_addr();
|
||||
*oop_addr = cast_to_oop(x);
|
||||
Bytes::put_native_u8((address)oop_addr, x);
|
||||
break;
|
||||
} else if (iter.type() == relocInfo::metadata_type) {
|
||||
Metadata** metadata_addr = iter.metadata_reloc()->metadata_addr();
|
||||
*metadata_addr = (Metadata*)x;
|
||||
Bytes::put_native_u8((address)metadata_addr, x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -343,7 +343,7 @@ bool NativeInstruction::is_sigill_zombie_not_entrant() {
|
||||
|
||||
void NativeIllegalInstruction::insert(address code_pos) {
|
||||
assert_cond(code_pos != NULL);
|
||||
*(juint*)code_pos = 0xffffffff; // all bits ones is permanently reserved as an illegal instruction
|
||||
Assembler::sd_instr(code_pos, 0xffffffff); // all bits ones is permanently reserved as an illegal instruction
|
||||
}
|
||||
|
||||
bool NativeInstruction::is_stop() {
|
||||
@@ -379,7 +379,7 @@ void NativeJump::patch_verified_entry(address entry, address verified_entry, add
|
||||
Assembler::patch(pInsn, 19, 12, (offset >> 12) & 0xff);
|
||||
Assembler::patch(pInsn, 11, 7, 0); // zero, no link jump
|
||||
Assembler::patch(pInsn, 6, 0, 0b1101111); // j, (jal x0 offset)
|
||||
*(unsigned int*)verified_entry = insn;
|
||||
Assembler::sd_instr(verified_entry, insn);
|
||||
} else {
|
||||
// We use an illegal instruction for marking a method as
|
||||
// not_entrant or zombie.
|
||||
@@ -437,5 +437,5 @@ void NativeMembar::set_kind(uint32_t order_kind) {
|
||||
Assembler::patch(pInsn, 23, 20, successor);
|
||||
|
||||
address membar = addr_at(0);
|
||||
*(unsigned int*) membar = insn;
|
||||
Assembler::sd_instr(membar, insn);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class NativeInstruction {
|
||||
assert_cond(instr != NULL);
|
||||
return (extract_opcode(instr) == 0b0010011 && // opcode field
|
||||
extract_funct3(instr) == 0b001 && // funct3 field, select the type of operation
|
||||
Assembler::extract(((unsigned*)instr)[0], 25, 20) == shift); // shamt field
|
||||
Assembler::extract(Assembler::ld_instr(instr), 25, 20) == shift); // shamt field
|
||||
}
|
||||
|
||||
static Register extract_rs1(address instr);
|
||||
@@ -203,18 +203,18 @@ class NativeInstruction {
|
||||
protected:
|
||||
address addr_at(int offset) const { return address(this) + offset; }
|
||||
|
||||
jint int_at(int offset) const { return *(jint*) addr_at(offset); }
|
||||
juint uint_at(int offset) const { return *(juint*) addr_at(offset); }
|
||||
jint int_at(int offset) const { return (jint)Bytes::get_native_u4(addr_at(offset)); }
|
||||
juint uint_at(int offset) const { return Bytes::get_native_u4(addr_at(offset)); }
|
||||
|
||||
address ptr_at(int offset) const { return *(address*) addr_at(offset); }
|
||||
address ptr_at(int offset) const { return (address)Bytes::get_native_u8(addr_at(offset)); }
|
||||
|
||||
oop oop_at (int offset) const { return *(oop*) addr_at(offset); }
|
||||
oop oop_at (int offset) const { return cast_to_oop(Bytes::get_native_u8(addr_at(offset))); }
|
||||
|
||||
|
||||
void set_int_at(int offset, jint i) { *(jint*)addr_at(offset) = i; }
|
||||
void set_uint_at(int offset, jint i) { *(juint*)addr_at(offset) = i; }
|
||||
void set_ptr_at (int offset, address ptr) { *(address*) addr_at(offset) = ptr; }
|
||||
void set_oop_at (int offset, oop o) { *(oop*) addr_at(offset) = o; }
|
||||
void set_int_at(int offset, jint i) { Bytes::put_native_u4(addr_at(offset), i); }
|
||||
void set_uint_at(int offset, jint i) { Bytes::put_native_u4(addr_at(offset), i); }
|
||||
void set_ptr_at (int offset, address ptr) { Bytes::put_native_u8(addr_at(offset), (u8)ptr); }
|
||||
void set_oop_at (int offset, oop o) { Bytes::put_native_u8(addr_at(offset), cast_from_oop<u8>(o)); }
|
||||
|
||||
public:
|
||||
|
||||
@@ -485,7 +485,7 @@ class NativeIllegalInstruction: public NativeInstruction {
|
||||
};
|
||||
|
||||
inline bool NativeInstruction::is_nop() {
|
||||
uint32_t insn = *(uint32_t*)addr_at(0);
|
||||
uint32_t insn = Assembler::ld_instr(addr_at(0));
|
||||
return insn == 0x13;
|
||||
}
|
||||
|
||||
@@ -527,7 +527,7 @@ inline bool is_NativeCallTrampolineStub_at(address addr) {
|
||||
(NativeInstruction::extract_rd(addr + instr_size) == x5) &&
|
||||
(NativeInstruction::extract_rs1(addr + instr_size) == x5) &&
|
||||
(NativeInstruction::extract_rs1(addr + 2 * instr_size) == x5) &&
|
||||
(Assembler::extract(((unsigned*)addr)[1], 31, 20) == NativeCallTrampolineStub::data_offset)) {
|
||||
(Assembler::extract(Assembler::ld_instr(addr + 4), 31, 20) == NativeCallTrampolineStub::data_offset)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#define CPU_RISCV_REGISTER_RISCV_HPP
|
||||
|
||||
#include "asm/register.hpp"
|
||||
#include "utilities/population_count.hpp"
|
||||
#include "utilities/powerOfTwo.hpp"
|
||||
|
||||
#define CSR_FFLAGS 0x001 // Floating-Point Accrued Exceptions.
|
||||
#define CSR_FRM 0x002 // Floating-Point Dynamic Rounding Mode.
|
||||
@@ -318,6 +320,8 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl {
|
||||
static const int max_vpr;
|
||||
};
|
||||
|
||||
template <class RegImpl> class RegSetIterator;
|
||||
|
||||
// A set of registers
|
||||
template<class RegImpl>
|
||||
class AbstractRegSet {
|
||||
@@ -325,7 +329,7 @@ class AbstractRegSet {
|
||||
|
||||
AbstractRegSet(uint32_t bitset) : _bitset(bitset) { }
|
||||
|
||||
public:
|
||||
public:
|
||||
AbstractRegSet() : _bitset(0) { }
|
||||
|
||||
AbstractRegSet(RegImpl r1) : _bitset(1 << r1->encoding()) { }
|
||||
@@ -375,11 +379,73 @@ class AbstractRegSet {
|
||||
return AbstractRegSet(bits);
|
||||
}
|
||||
|
||||
uint size() const { return population_count(_bitset); }
|
||||
|
||||
uint32_t bits() const { return _bitset; }
|
||||
|
||||
private:
|
||||
|
||||
RegImpl first();
|
||||
|
||||
public:
|
||||
|
||||
friend class RegSetIterator<RegImpl>;
|
||||
|
||||
RegSetIterator<RegImpl> begin();
|
||||
};
|
||||
|
||||
typedef AbstractRegSet<Register> RegSet;
|
||||
typedef AbstractRegSet<FloatRegister> FloatRegSet;
|
||||
typedef AbstractRegSet<VectorRegister> VectorRegSet;
|
||||
|
||||
template <class RegImpl>
|
||||
class RegSetIterator {
|
||||
AbstractRegSet<RegImpl> _regs;
|
||||
|
||||
public:
|
||||
RegSetIterator(AbstractRegSet<RegImpl> x): _regs(x) {}
|
||||
RegSetIterator(const RegSetIterator& mit) : _regs(mit._regs) {}
|
||||
|
||||
RegSetIterator& operator++() {
|
||||
RegImpl r = _regs.first();
|
||||
if (r->is_valid())
|
||||
_regs -= r;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const RegSetIterator& rhs) const {
|
||||
return _regs.bits() == rhs._regs.bits();
|
||||
}
|
||||
bool operator!=(const RegSetIterator& rhs) const {
|
||||
return ! (rhs == *this);
|
||||
}
|
||||
|
||||
RegImpl operator*() {
|
||||
return _regs.first();
|
||||
}
|
||||
};
|
||||
|
||||
template <class RegImpl>
|
||||
inline RegSetIterator<RegImpl> AbstractRegSet<RegImpl>::begin() {
|
||||
return RegSetIterator<RegImpl>(*this);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Register AbstractRegSet<Register>::first() {
|
||||
uint32_t first = _bitset & -_bitset;
|
||||
return first ? as_Register(exact_log2(first)) : noreg;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline FloatRegister AbstractRegSet<FloatRegister>::first() {
|
||||
uint32_t first = _bitset & -_bitset;
|
||||
return first ? as_FloatRegister(exact_log2(first)) : fnoreg;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline VectorRegister AbstractRegSet<VectorRegister>::first() {
|
||||
uint32_t first = _bitset & -_bitset;
|
||||
return first ? as_VectorRegister(exact_log2(first)) : vnoreg;
|
||||
}
|
||||
|
||||
#endif // CPU_RISCV_REGISTER_RISCV_HPP
|
||||
|
||||
@@ -45,7 +45,7 @@ void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
|
||||
if (NativeInstruction::is_load_pc_relative_at(addr())) {
|
||||
address constptr = (address)code()->oop_addr_at(reloc->oop_index());
|
||||
bytes = MacroAssembler::pd_patch_instruction_size(addr(), constptr);
|
||||
assert(*(address*)constptr == x, "error in oop relocation");
|
||||
assert((address)Bytes::get_native_u8(constptr) == x, "error in oop relocation");
|
||||
} else {
|
||||
bytes = MacroAssembler::patch_oop(addr(), x);
|
||||
}
|
||||
|
||||
@@ -2318,7 +2318,7 @@ encode %{
|
||||
if (DiagnoseSyncOnValueBasedClasses != 0) {
|
||||
__ load_klass(flag, oop);
|
||||
__ lwu(flag, Address(flag, Klass::access_flags_offset()));
|
||||
__ test_bit(flag, flag, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS), tmp /* tmp */);
|
||||
__ test_bit(flag, flag, exact_log2(JVM_ACC_IS_VALUE_BASED_CLASS));
|
||||
__ bnez(flag, cont, true /* is_far */);
|
||||
}
|
||||
|
||||
|
||||
@@ -2311,24 +2311,21 @@ class StubGenerator: public StubCodeGenerator {
|
||||
}
|
||||
|
||||
// code for comparing 8 characters of strings with Latin1 and Utf16 encoding
|
||||
void compare_string_8_x_LU(Register tmpL, Register tmpU, Label &DIFF1,
|
||||
Label &DIFF2) {
|
||||
const Register strU = x12, curU = x7, strL = x29, tmp = x30;
|
||||
__ ld(tmpL, Address(strL));
|
||||
__ addi(strL, strL, 8);
|
||||
void compare_string_8_x_LU(Register tmpL, Register tmpU, Register strL, Register strU, Label& DIFF) {
|
||||
const Register tmp = x30, tmpLval = x12;
|
||||
__ ld(tmpLval, Address(strL));
|
||||
__ addi(strL, strL, wordSize);
|
||||
__ ld(tmpU, Address(strU));
|
||||
__ addi(strU, strU, 8);
|
||||
__ inflate_lo32(tmp, tmpL);
|
||||
__ mv(t0, tmp);
|
||||
__ xorr(tmp, curU, t0);
|
||||
__ bnez(tmp, DIFF2);
|
||||
__ addi(strU, strU, wordSize);
|
||||
__ inflate_lo32(tmpL, tmpLval);
|
||||
__ xorr(tmp, tmpU, tmpL);
|
||||
__ bnez(tmp, DIFF);
|
||||
|
||||
__ ld(curU, Address(strU));
|
||||
__ addi(strU, strU, 8);
|
||||
__ inflate_hi32(tmp, tmpL);
|
||||
__ mv(t0, tmp);
|
||||
__ xorr(tmp, tmpU, t0);
|
||||
__ bnez(tmp, DIFF1);
|
||||
__ ld(tmpU, Address(strU));
|
||||
__ addi(strU, strU, wordSize);
|
||||
__ inflate_hi32(tmpL, tmpLval);
|
||||
__ xorr(tmp, tmpU, tmpL);
|
||||
__ bnez(tmp, DIFF);
|
||||
}
|
||||
|
||||
// x10 = result
|
||||
@@ -2343,11 +2340,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ align(CodeEntryAlignment);
|
||||
StubCodeMark mark(this, "StubRoutines", isLU ? "compare_long_string_different_encoding LU" : "compare_long_string_different_encoding UL");
|
||||
address entry = __ pc();
|
||||
Label SMALL_LOOP, TAIL, TAIL_LOAD_16, LOAD_LAST, DIFF1, DIFF2,
|
||||
DONE, CALCULATE_DIFFERENCE;
|
||||
const Register result = x10, str1 = x11, cnt1 = x12, str2 = x13, cnt2 = x14,
|
||||
tmp1 = x28, tmp2 = x29, tmp3 = x30, tmp4 = x7, tmp5 = x31;
|
||||
RegSet spilled_regs = RegSet::of(tmp4, tmp5);
|
||||
Label SMALL_LOOP, TAIL, LOAD_LAST, DONE, CALCULATE_DIFFERENCE;
|
||||
const Register result = x10, str1 = x11, str2 = x13, cnt2 = x14,
|
||||
tmp1 = x28, tmp2 = x29, tmp3 = x30, tmp4 = x12;
|
||||
|
||||
// cnt2 == amount of characters left to compare
|
||||
// Check already loaded first 4 symbols
|
||||
@@ -2355,77 +2350,81 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ mv(isLU ? tmp1 : tmp2, tmp3);
|
||||
__ addi(str1, str1, isLU ? wordSize / 2 : wordSize);
|
||||
__ addi(str2, str2, isLU ? wordSize : wordSize / 2);
|
||||
__ sub(cnt2, cnt2, 8); // Already loaded 4 symbols. Last 4 is special case.
|
||||
__ push_reg(spilled_regs, sp);
|
||||
__ sub(cnt2, cnt2, wordSize / 2); // Already loaded 4 symbols
|
||||
|
||||
if (isLU) {
|
||||
__ add(str1, str1, cnt2);
|
||||
__ shadd(str2, cnt2, str2, t0, 1);
|
||||
} else {
|
||||
__ shadd(str1, cnt2, str1, t0, 1);
|
||||
__ add(str2, str2, cnt2);
|
||||
}
|
||||
__ xorr(tmp3, tmp1, tmp2);
|
||||
__ mv(tmp5, tmp2);
|
||||
__ bnez(tmp3, CALCULATE_DIFFERENCE);
|
||||
|
||||
Register strU = isLU ? str2 : str1,
|
||||
strL = isLU ? str1 : str2,
|
||||
tmpU = isLU ? tmp5 : tmp1, // where to keep U for comparison
|
||||
tmpL = isLU ? tmp1 : tmp5; // where to keep L for comparison
|
||||
tmpU = isLU ? tmp2 : tmp1, // where to keep U for comparison
|
||||
tmpL = isLU ? tmp1 : tmp2; // where to keep L for comparison
|
||||
|
||||
__ sub(tmp2, strL, cnt2); // strL pointer to load from
|
||||
__ slli(t0, cnt2, 1);
|
||||
__ sub(cnt1, strU, t0); // strU pointer to load from
|
||||
// make sure main loop is 8 byte-aligned, we should load another 4 bytes from strL
|
||||
// cnt2 is >= 68 here, no need to check it for >= 0
|
||||
__ lwu(tmpL, Address(strL));
|
||||
__ addi(strL, strL, wordSize / 2);
|
||||
__ ld(tmpU, Address(strU));
|
||||
__ addi(strU, strU, wordSize);
|
||||
__ inflate_lo32(tmp3, tmpL);
|
||||
__ mv(tmpL, tmp3);
|
||||
__ xorr(tmp3, tmpU, tmpL);
|
||||
__ bnez(tmp3, CALCULATE_DIFFERENCE);
|
||||
__ addi(cnt2, cnt2, -wordSize / 2);
|
||||
|
||||
__ ld(tmp4, Address(cnt1));
|
||||
__ addi(cnt1, cnt1, 8);
|
||||
__ beqz(cnt2, LOAD_LAST); // no characters left except last load
|
||||
__ sub(cnt2, cnt2, 16);
|
||||
// we are now 8-bytes aligned on strL
|
||||
__ sub(cnt2, cnt2, wordSize * 2);
|
||||
__ bltz(cnt2, TAIL);
|
||||
__ bind(SMALL_LOOP); // smaller loop
|
||||
__ sub(cnt2, cnt2, 16);
|
||||
compare_string_8_x_LU(tmpL, tmpU, DIFF1, DIFF2);
|
||||
compare_string_8_x_LU(tmpL, tmpU, DIFF1, DIFF2);
|
||||
__ sub(cnt2, cnt2, wordSize * 2);
|
||||
compare_string_8_x_LU(tmpL, tmpU, strL, strU, CALCULATE_DIFFERENCE);
|
||||
compare_string_8_x_LU(tmpL, tmpU, strL, strU, CALCULATE_DIFFERENCE);
|
||||
__ bgez(cnt2, SMALL_LOOP);
|
||||
__ addi(t0, cnt2, 16);
|
||||
__ beqz(t0, LOAD_LAST);
|
||||
__ bind(TAIL); // 1..15 characters left until last load (last 4 characters)
|
||||
// Address of 8 bytes before last 4 characters in UTF-16 string
|
||||
__ shadd(cnt1, cnt2, cnt1, t0, 1);
|
||||
// Address of 16 bytes before last 4 characters in Latin1 string
|
||||
__ add(tmp2, tmp2, cnt2);
|
||||
__ ld(tmp4, Address(cnt1, -8));
|
||||
// last 16 characters before last load
|
||||
compare_string_8_x_LU(tmpL, tmpU, DIFF1, DIFF2);
|
||||
compare_string_8_x_LU(tmpL, tmpU, DIFF1, DIFF2);
|
||||
__ j(LOAD_LAST);
|
||||
__ bind(DIFF2);
|
||||
__ mv(tmpU, tmp4);
|
||||
__ bind(DIFF1);
|
||||
__ mv(tmpL, t0);
|
||||
__ j(CALCULATE_DIFFERENCE);
|
||||
__ bind(LOAD_LAST);
|
||||
// Last 4 UTF-16 characters are already pre-loaded into tmp4 by compare_string_8_x_LU.
|
||||
// No need to load it again
|
||||
__ mv(tmpU, tmp4);
|
||||
__ ld(tmpL, Address(strL));
|
||||
__ addi(t0, cnt2, wordSize * 2);
|
||||
__ beqz(t0, DONE);
|
||||
__ bind(TAIL); // 1..15 characters left
|
||||
// Aligned access. Load bytes in portions - 4, 2, 1.
|
||||
|
||||
__ addi(t0, cnt2, wordSize);
|
||||
__ addi(cnt2, cnt2, wordSize * 2); // amount of characters left to process
|
||||
__ bltz(t0, LOAD_LAST);
|
||||
// remaining characters are greater than or equals to 8, we can do one compare_string_8_x_LU
|
||||
compare_string_8_x_LU(tmpL, tmpU, strL, strU, CALCULATE_DIFFERENCE);
|
||||
__ addi(cnt2, cnt2, -wordSize);
|
||||
__ beqz(cnt2, DONE); // no character left
|
||||
__ bind(LOAD_LAST); // cnt2 = 1..7 characters left
|
||||
|
||||
__ addi(cnt2, cnt2, -wordSize); // cnt2 is now an offset in strL which points to last 8 bytes
|
||||
__ slli(t0, cnt2, 1); // t0 is now an offset in strU which points to last 16 bytes
|
||||
__ add(strL, strL, cnt2); // Address of last 8 bytes in Latin1 string
|
||||
__ add(strU, strU, t0); // Address of last 16 bytes in UTF-16 string
|
||||
__ load_int_misaligned(tmpL, Address(strL), t0, false);
|
||||
__ load_long_misaligned(tmpU, Address(strU), t0, 2);
|
||||
__ inflate_lo32(tmp3, tmpL);
|
||||
__ mv(tmpL, tmp3);
|
||||
__ xorr(tmp3, tmpU, tmpL);
|
||||
__ beqz(tmp3, DONE);
|
||||
__ bnez(tmp3, CALCULATE_DIFFERENCE);
|
||||
|
||||
__ addi(strL, strL, wordSize / 2); // Address of last 4 bytes in Latin1 string
|
||||
__ addi(strU, strU, wordSize); // Address of last 8 bytes in UTF-16 string
|
||||
__ load_int_misaligned(tmpL, Address(strL), t0, false);
|
||||
__ load_long_misaligned(tmpU, Address(strU), t0, 2);
|
||||
__ inflate_lo32(tmp3, tmpL);
|
||||
__ mv(tmpL, tmp3);
|
||||
__ xorr(tmp3, tmpU, tmpL);
|
||||
__ bnez(tmp3, CALCULATE_DIFFERENCE);
|
||||
__ j(DONE); // no character left
|
||||
|
||||
// Find the first different characters in the longwords and
|
||||
// compute their difference.
|
||||
__ bind(CALCULATE_DIFFERENCE);
|
||||
__ ctzc_bit(tmp4, tmp3);
|
||||
__ srl(tmp1, tmp1, tmp4);
|
||||
__ srl(tmp5, tmp5, tmp4);
|
||||
__ srl(tmp2, tmp2, tmp4);
|
||||
__ andi(tmp1, tmp1, 0xFFFF);
|
||||
__ andi(tmp5, tmp5, 0xFFFF);
|
||||
__ sub(result, tmp1, tmp5);
|
||||
__ andi(tmp2, tmp2, 0xFFFF);
|
||||
__ sub(result, tmp1, tmp2);
|
||||
__ bind(DONE);
|
||||
__ pop_reg(spilled_regs, sp);
|
||||
__ ret();
|
||||
return entry;
|
||||
}
|
||||
@@ -2527,9 +2526,9 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ xorr(tmp4, tmp1, tmp2);
|
||||
__ bnez(tmp4, DIFF);
|
||||
__ add(str1, str1, cnt2);
|
||||
__ ld(tmp5, Address(str1));
|
||||
__ load_long_misaligned(tmp5, Address(str1), tmp3, isLL ? 1 : 2);
|
||||
__ add(str2, str2, cnt2);
|
||||
__ ld(cnt1, Address(str2));
|
||||
__ load_long_misaligned(cnt1, Address(str2), tmp3, isLL ? 1 : 2);
|
||||
__ xorr(tmp4, tmp5, cnt1);
|
||||
__ beqz(tmp4, LENGTH_DIFF);
|
||||
// Find the first different characters in the longwords and
|
||||
@@ -3686,6 +3685,375 @@ class StubGenerator: public StubCodeGenerator {
|
||||
};
|
||||
#endif // COMPILER2
|
||||
|
||||
// Set of L registers that correspond to a contiguous memory area.
|
||||
// Each 64-bit register typically corresponds to 2 32-bit integers.
|
||||
template <uint L>
|
||||
class RegCache {
|
||||
private:
|
||||
MacroAssembler *_masm;
|
||||
Register _regs[L];
|
||||
|
||||
public:
|
||||
RegCache(MacroAssembler *masm, RegSet rs): _masm(masm) {
|
||||
assert(rs.size() == L, "%u registers are used to cache %u 4-byte data", rs.size(), 2 * L);
|
||||
auto it = rs.begin();
|
||||
for (auto &r: _regs) {
|
||||
r = *it;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
// generate load for the i'th register
|
||||
void gen_load(uint i, Register base) {
|
||||
assert(i < L, "invalid i: %u", i);
|
||||
__ ld(_regs[i], Address(base, 8 * i));
|
||||
}
|
||||
|
||||
// add i'th 32-bit integer to dest
|
||||
void add_u32(const Register dest, uint i, const Register rtmp = t0) {
|
||||
assert(i < 2 * L, "invalid i: %u", i);
|
||||
|
||||
if (is_even(i)) {
|
||||
// Use the bottom 32 bits. No need to mask off the top 32 bits
|
||||
// as addw will do the right thing.
|
||||
__ addw(dest, dest, _regs[i / 2]);
|
||||
} else {
|
||||
// Use the top 32 bits by right-shifting them.
|
||||
__ srli(rtmp, _regs[i / 2], 32);
|
||||
__ addw(dest, dest, rtmp);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef RegCache<8> BufRegCache;
|
||||
|
||||
// a += value + x + ac;
|
||||
// a = Integer.rotateLeft(a, s) + b;
|
||||
void m5_FF_GG_HH_II_epilogue(BufRegCache& reg_cache,
|
||||
Register a, Register b, Register c, Register d,
|
||||
int k, int s, int t,
|
||||
Register value) {
|
||||
// a += ac
|
||||
__ addw(a, a, t, t1);
|
||||
|
||||
// a += x;
|
||||
reg_cache.add_u32(a, k);
|
||||
// a += value;
|
||||
__ addw(a, a, value);
|
||||
|
||||
// a = Integer.rotateLeft(a, s) + b;
|
||||
__ rolw_imm(a, a, s);
|
||||
__ addw(a, a, b);
|
||||
}
|
||||
|
||||
// a += ((b & c) | ((~b) & d)) + x + ac;
|
||||
// a = Integer.rotateLeft(a, s) + b;
|
||||
void md5_FF(BufRegCache& reg_cache,
|
||||
Register a, Register b, Register c, Register d,
|
||||
int k, int s, int t,
|
||||
Register rtmp1, Register rtmp2) {
|
||||
// rtmp1 = b & c
|
||||
__ andr(rtmp1, b, c);
|
||||
|
||||
// rtmp2 = (~b) & d
|
||||
__ andn(rtmp2, d, b);
|
||||
|
||||
// rtmp1 = (b & c) | ((~b) & d)
|
||||
__ orr(rtmp1, rtmp1, rtmp2);
|
||||
|
||||
m5_FF_GG_HH_II_epilogue(reg_cache, a, b, c, d, k, s, t, rtmp1);
|
||||
}
|
||||
|
||||
// a += ((b & d) | (c & (~d))) + x + ac;
|
||||
// a = Integer.rotateLeft(a, s) + b;
|
||||
void md5_GG(BufRegCache& reg_cache,
|
||||
Register a, Register b, Register c, Register d,
|
||||
int k, int s, int t,
|
||||
Register rtmp1, Register rtmp2) {
|
||||
// rtmp1 = b & d
|
||||
__ andr(rtmp1, b, d);
|
||||
|
||||
// rtmp2 = c & (~d)
|
||||
__ andn(rtmp2, c, d);
|
||||
|
||||
// rtmp1 = (b & d) | (c & (~d))
|
||||
__ orr(rtmp1, rtmp1, rtmp2);
|
||||
|
||||
m5_FF_GG_HH_II_epilogue(reg_cache, a, b, c, d, k, s, t, rtmp1);
|
||||
}
|
||||
|
||||
// a += ((b ^ c) ^ d) + x + ac;
|
||||
// a = Integer.rotateLeft(a, s) + b;
|
||||
void md5_HH(BufRegCache& reg_cache,
|
||||
Register a, Register b, Register c, Register d,
|
||||
int k, int s, int t,
|
||||
Register rtmp1, Register rtmp2) {
|
||||
// rtmp1 = (b ^ c) ^ d
|
||||
__ xorr(rtmp2, b, c);
|
||||
__ xorr(rtmp1, rtmp2, d);
|
||||
|
||||
m5_FF_GG_HH_II_epilogue(reg_cache, a, b, c, d, k, s, t, rtmp1);
|
||||
}
|
||||
|
||||
// a += (c ^ (b | (~d))) + x + ac;
|
||||
// a = Integer.rotateLeft(a, s) + b;
|
||||
void md5_II(BufRegCache& reg_cache,
|
||||
Register a, Register b, Register c, Register d,
|
||||
int k, int s, int t,
|
||||
Register rtmp1, Register rtmp2) {
|
||||
// rtmp1 = c ^ (b | (~d))
|
||||
__ orn(rtmp2, b, d);
|
||||
__ xorr(rtmp1, c, rtmp2);
|
||||
|
||||
m5_FF_GG_HH_II_epilogue(reg_cache, a, b, c, d, k, s, t, rtmp1);
|
||||
}
|
||||
|
||||
// Arguments:
|
||||
//
|
||||
// Inputs:
|
||||
// c_rarg0 - byte[] source+offset
|
||||
// c_rarg1 - int[] SHA.state
|
||||
// c_rarg2 - int offset (multi_block == True)
|
||||
// c_rarg3 - int limit (multi_block == True)
|
||||
//
|
||||
// Registers:
|
||||
// x0 zero (zero)
|
||||
// x1 ra (return address)
|
||||
// x2 sp (stack pointer)
|
||||
// x3 gp (global pointer)
|
||||
// x4 tp (thread pointer)
|
||||
// x5 t0 (tmp register)
|
||||
// x6 t1 (tmp register)
|
||||
// x7 t2 state0
|
||||
// x8 f0/s0 (frame pointer)
|
||||
// x9 s1
|
||||
// x10 a0 rtmp1 / c_rarg0
|
||||
// x11 a1 rtmp2 / c_rarg1
|
||||
// x12 a2 a / c_rarg2
|
||||
// x13 a3 b / c_rarg3
|
||||
// x14 a4 c
|
||||
// x15 a5 d
|
||||
// x16 a6 buf
|
||||
// x17 a7 state
|
||||
// x18 s2 ofs [saved-reg] (multi_block == True)
|
||||
// x19 s3 limit [saved-reg] (multi_block == True)
|
||||
// x20 s4 state1 [saved-reg]
|
||||
// x21 s5 state2 [saved-reg]
|
||||
// x22 s6 state3 [saved-reg]
|
||||
// x23 s7
|
||||
// x24 s8 buf0 [saved-reg]
|
||||
// x25 s9 buf1 [saved-reg]
|
||||
// x26 s10 buf2 [saved-reg]
|
||||
// x27 s11 buf3 [saved-reg]
|
||||
// x28 t3 buf4
|
||||
// x29 t4 buf5
|
||||
// x30 t5 buf6
|
||||
// x31 t6 buf7
|
||||
address generate_md5_implCompress(bool multi_block, const char *name) {
|
||||
__ align(CodeEntryAlignment);
|
||||
StubCodeMark mark(this, "StubRoutines", name);
|
||||
address start = __ pc();
|
||||
|
||||
// rotation constants
|
||||
const int S11 = 7;
|
||||
const int S12 = 12;
|
||||
const int S13 = 17;
|
||||
const int S14 = 22;
|
||||
const int S21 = 5;
|
||||
const int S22 = 9;
|
||||
const int S23 = 14;
|
||||
const int S24 = 20;
|
||||
const int S31 = 4;
|
||||
const int S32 = 11;
|
||||
const int S33 = 16;
|
||||
const int S34 = 23;
|
||||
const int S41 = 6;
|
||||
const int S42 = 10;
|
||||
const int S43 = 15;
|
||||
const int S44 = 21;
|
||||
|
||||
const int64_t mask32 = 0xffffffff;
|
||||
|
||||
Register buf_arg = c_rarg0; // a0
|
||||
Register state_arg = c_rarg1; // a1
|
||||
Register ofs_arg = c_rarg2; // a2
|
||||
Register limit_arg = c_rarg3; // a3
|
||||
|
||||
// we'll copy the args to these registers to free up a0-a3
|
||||
// to use for other values manipulated by instructions
|
||||
// that can be compressed
|
||||
Register buf = x16; // a6
|
||||
Register state = x17; // a7
|
||||
Register ofs = x18; // s2
|
||||
Register limit = x19; // s3
|
||||
|
||||
// using x12->15 to allow compressed instructions
|
||||
Register a = x12; // a2
|
||||
Register b = x13; // a3
|
||||
Register c = x14; // a4
|
||||
Register d = x15; // a5
|
||||
|
||||
Register state0 = x7; // t2
|
||||
Register state1 = x20; // s4
|
||||
Register state2 = x21; // s5
|
||||
Register state3 = x22; // s6
|
||||
|
||||
// using x10->x11 to allow compressed instructions
|
||||
Register rtmp1 = x10; // a0
|
||||
Register rtmp2 = x11; // a1
|
||||
|
||||
RegSet reg_cache_saved_regs = RegSet::of(x24, x25, x26, x27); // s8, s9, s10, s11
|
||||
RegSet reg_cache_regs;
|
||||
reg_cache_regs += reg_cache_saved_regs;
|
||||
reg_cache_regs += RegSet::of(x28, x29, x30, x31); // t3, t4, t5, t6
|
||||
BufRegCache reg_cache(_masm, reg_cache_regs);
|
||||
|
||||
RegSet saved_regs;
|
||||
if (multi_block) {
|
||||
saved_regs += RegSet::of(ofs, limit);
|
||||
}
|
||||
saved_regs += RegSet::of(state1, state2, state3);
|
||||
saved_regs += reg_cache_saved_regs;
|
||||
|
||||
__ push_reg(saved_regs, sp);
|
||||
|
||||
__ mv(buf, buf_arg);
|
||||
__ mv(state, state_arg);
|
||||
if (multi_block) {
|
||||
__ mv(ofs, ofs_arg);
|
||||
__ mv(limit, limit_arg);
|
||||
}
|
||||
|
||||
// to minimize the number of memory operations:
|
||||
// read the 4 state 4-byte values in pairs, with a single ld,
|
||||
// and split them into 2 registers
|
||||
__ mv(t0, mask32);
|
||||
__ ld(state0, Address(state));
|
||||
__ srli(state1, state0, 32);
|
||||
__ andr(state0, state0, t0);
|
||||
__ ld(state2, Address(state, 8));
|
||||
__ srli(state3, state2, 32);
|
||||
__ andr(state2, state2, t0);
|
||||
|
||||
Label md5_loop;
|
||||
__ BIND(md5_loop);
|
||||
|
||||
__ mv(a, state0);
|
||||
__ mv(b, state1);
|
||||
__ mv(c, state2);
|
||||
__ mv(d, state3);
|
||||
|
||||
// Round 1
|
||||
reg_cache.gen_load(0, buf);
|
||||
md5_FF(reg_cache, a, b, c, d, 0, S11, 0xd76aa478, rtmp1, rtmp2);
|
||||
md5_FF(reg_cache, d, a, b, c, 1, S12, 0xe8c7b756, rtmp1, rtmp2);
|
||||
reg_cache.gen_load(1, buf);
|
||||
md5_FF(reg_cache, c, d, a, b, 2, S13, 0x242070db, rtmp1, rtmp2);
|
||||
md5_FF(reg_cache, b, c, d, a, 3, S14, 0xc1bdceee, rtmp1, rtmp2);
|
||||
reg_cache.gen_load(2, buf);
|
||||
md5_FF(reg_cache, a, b, c, d, 4, S11, 0xf57c0faf, rtmp1, rtmp2);
|
||||
md5_FF(reg_cache, d, a, b, c, 5, S12, 0x4787c62a, rtmp1, rtmp2);
|
||||
reg_cache.gen_load(3, buf);
|
||||
md5_FF(reg_cache, c, d, a, b, 6, S13, 0xa8304613, rtmp1, rtmp2);
|
||||
md5_FF(reg_cache, b, c, d, a, 7, S14, 0xfd469501, rtmp1, rtmp2);
|
||||
reg_cache.gen_load(4, buf);
|
||||
md5_FF(reg_cache, a, b, c, d, 8, S11, 0x698098d8, rtmp1, rtmp2);
|
||||
md5_FF(reg_cache, d, a, b, c, 9, S12, 0x8b44f7af, rtmp1, rtmp2);
|
||||
reg_cache.gen_load(5, buf);
|
||||
md5_FF(reg_cache, c, d, a, b, 10, S13, 0xffff5bb1, rtmp1, rtmp2);
|
||||
md5_FF(reg_cache, b, c, d, a, 11, S14, 0x895cd7be, rtmp1, rtmp2);
|
||||
reg_cache.gen_load(6, buf);
|
||||
md5_FF(reg_cache, a, b, c, d, 12, S11, 0x6b901122, rtmp1, rtmp2);
|
||||
md5_FF(reg_cache, d, a, b, c, 13, S12, 0xfd987193, rtmp1, rtmp2);
|
||||
reg_cache.gen_load(7, buf);
|
||||
md5_FF(reg_cache, c, d, a, b, 14, S13, 0xa679438e, rtmp1, rtmp2);
|
||||
md5_FF(reg_cache, b, c, d, a, 15, S14, 0x49b40821, rtmp1, rtmp2);
|
||||
|
||||
// Round 2
|
||||
md5_GG(reg_cache, a, b, c, d, 1, S21, 0xf61e2562, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, d, a, b, c, 6, S22, 0xc040b340, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, c, d, a, b, 11, S23, 0x265e5a51, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, b, c, d, a, 0, S24, 0xe9b6c7aa, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, a, b, c, d, 5, S21, 0xd62f105d, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, d, a, b, c, 10, S22, 0x02441453, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, c, d, a, b, 15, S23, 0xd8a1e681, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, b, c, d, a, 4, S24, 0xe7d3fbc8, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, a, b, c, d, 9, S21, 0x21e1cde6, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, d, a, b, c, 14, S22, 0xc33707d6, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, c, d, a, b, 3, S23, 0xf4d50d87, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, b, c, d, a, 8, S24, 0x455a14ed, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, a, b, c, d, 13, S21, 0xa9e3e905, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, d, a, b, c, 2, S22, 0xfcefa3f8, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, c, d, a, b, 7, S23, 0x676f02d9, rtmp1, rtmp2);
|
||||
md5_GG(reg_cache, b, c, d, a, 12, S24, 0x8d2a4c8a, rtmp1, rtmp2);
|
||||
|
||||
// Round 3
|
||||
md5_HH(reg_cache, a, b, c, d, 5, S31, 0xfffa3942, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, d, a, b, c, 8, S32, 0x8771f681, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, c, d, a, b, 11, S33, 0x6d9d6122, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, b, c, d, a, 14, S34, 0xfde5380c, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, a, b, c, d, 1, S31, 0xa4beea44, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, d, a, b, c, 4, S32, 0x4bdecfa9, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, c, d, a, b, 7, S33, 0xf6bb4b60, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, b, c, d, a, 10, S34, 0xbebfbc70, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, a, b, c, d, 13, S31, 0x289b7ec6, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, d, a, b, c, 0, S32, 0xeaa127fa, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, c, d, a, b, 3, S33, 0xd4ef3085, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, b, c, d, a, 6, S34, 0x04881d05, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, a, b, c, d, 9, S31, 0xd9d4d039, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, d, a, b, c, 12, S32, 0xe6db99e5, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, c, d, a, b, 15, S33, 0x1fa27cf8, rtmp1, rtmp2);
|
||||
md5_HH(reg_cache, b, c, d, a, 2, S34, 0xc4ac5665, rtmp1, rtmp2);
|
||||
|
||||
// Round 4
|
||||
md5_II(reg_cache, a, b, c, d, 0, S41, 0xf4292244, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, d, a, b, c, 7, S42, 0x432aff97, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, c, d, a, b, 14, S43, 0xab9423a7, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, b, c, d, a, 5, S44, 0xfc93a039, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, a, b, c, d, 12, S41, 0x655b59c3, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, d, a, b, c, 3, S42, 0x8f0ccc92, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, c, d, a, b, 10, S43, 0xffeff47d, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, b, c, d, a, 1, S44, 0x85845dd1, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, a, b, c, d, 8, S41, 0x6fa87e4f, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, d, a, b, c, 15, S42, 0xfe2ce6e0, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, c, d, a, b, 6, S43, 0xa3014314, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, b, c, d, a, 13, S44, 0x4e0811a1, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, a, b, c, d, 4, S41, 0xf7537e82, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, d, a, b, c, 11, S42, 0xbd3af235, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, c, d, a, b, 2, S43, 0x2ad7d2bb, rtmp1, rtmp2);
|
||||
md5_II(reg_cache, b, c, d, a, 9, S44, 0xeb86d391, rtmp1, rtmp2);
|
||||
|
||||
__ addw(state0, state0, a);
|
||||
__ addw(state1, state1, b);
|
||||
__ addw(state2, state2, c);
|
||||
__ addw(state3, state3, d);
|
||||
|
||||
if (multi_block) {
|
||||
__ addi(buf, buf, 64);
|
||||
__ addi(ofs, ofs, 64);
|
||||
// if (ofs <= limit) goto m5_loop
|
||||
__ bge(limit, ofs, md5_loop);
|
||||
__ mv(c_rarg0, ofs); // return ofs
|
||||
}
|
||||
|
||||
// to minimize the number of memory operations:
|
||||
// write back the 4 state 4-byte values in pairs, with a single sd
|
||||
__ mv(t0, mask32);
|
||||
__ andr(state0, state0, t0);
|
||||
__ slli(state1, state1, 32);
|
||||
__ orr(state0, state0, state1);
|
||||
__ sd(state0, Address(state));
|
||||
__ andr(state2, state2, t0);
|
||||
__ slli(state3, state3, 32);
|
||||
__ orr(state2, state2, state3);
|
||||
__ sd(state2, Address(state, 8));
|
||||
|
||||
__ pop_reg(saved_regs, sp);
|
||||
__ ret();
|
||||
|
||||
return (address) start;
|
||||
}
|
||||
|
||||
// Continuation point for throwing of implicit exceptions that are
|
||||
// not handled in the current activation. Fabricates an exception
|
||||
// oop and initiates normal exception dispatching in this
|
||||
@@ -3882,6 +4250,11 @@ class StubGenerator: public StubCodeGenerator {
|
||||
|
||||
generate_string_indexof_stubs();
|
||||
|
||||
if (UseMD5Intrinsics) {
|
||||
StubRoutines::_md5_implCompress = generate_md5_implCompress(false, "md5_implCompress");
|
||||
StubRoutines::_md5_implCompressMB = generate_md5_implCompress(true, "md5_implCompressMB");
|
||||
}
|
||||
|
||||
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||
if (bs_nm != NULL) {
|
||||
StubRoutines::riscv::_method_entry_barrier = generate_method_entry_barrier();
|
||||
|
||||
@@ -36,8 +36,8 @@ static bool returns_to_call_stub(address return_pc) {
|
||||
}
|
||||
|
||||
enum platform_dependent_constants {
|
||||
code_size1 = 19000, // simply increase if too small (assembler will crash if too small)
|
||||
code_size2 = 28000 // simply increase if too small (assembler will crash if too small)
|
||||
code_size1 = 20000, // simply increase if too small (assembler will crash if too small)
|
||||
code_size2 = 30000 // simply increase if too small (assembler will crash if too small)
|
||||
};
|
||||
|
||||
class riscv {
|
||||
|
||||
@@ -1060,8 +1060,9 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
Label L;
|
||||
__ ld(x28, Address(xmethod, Method::native_function_offset()));
|
||||
address unsatisfied = (SharedRuntime::native_method_throw_unsatisfied_link_error_entry());
|
||||
__ mv(t1, unsatisfied);
|
||||
__ ld(t1, Address(t1, 0));
|
||||
__ mv(t, unsatisfied);
|
||||
__ load_long_misaligned(t1, Address(t, 0), t0, 2); // 2 bytes aligned, but not 4 or 8
|
||||
|
||||
__ bne(x28, t1, L);
|
||||
__ call_VM(noreg,
|
||||
CAST_FROM_FN_PTR(address,
|
||||
|
||||
@@ -288,9 +288,15 @@ void TemplateTable::bipush()
|
||||
void TemplateTable::sipush()
|
||||
{
|
||||
transition(vtos, itos);
|
||||
__ load_unsigned_short(x10, at_bcp(1));
|
||||
__ revb_w_w(x10, x10);
|
||||
__ sraiw(x10, x10, 16);
|
||||
if (AvoidUnalignedAccesses) {
|
||||
__ load_signed_byte(x10, at_bcp(1));
|
||||
__ load_unsigned_byte(t1, at_bcp(2));
|
||||
__ slli(x10, x10, 8);
|
||||
__ add(x10, x10, t1);
|
||||
} else {
|
||||
__ load_unsigned_short(x10, at_bcp(1));
|
||||
__ revb_h_h(x10, x10); // reverse bytes in half-word and sign-extend
|
||||
}
|
||||
}
|
||||
|
||||
void TemplateTable::ldc(bool wide)
|
||||
@@ -378,7 +384,8 @@ void TemplateTable::fast_aldc(bool wide)
|
||||
// We are resolved if the resolved reference cache entry contains a
|
||||
// non-null object (String, MethodType, etc.)
|
||||
assert_different_registers(result, tmp);
|
||||
__ get_cache_index_at_bcp(tmp, 1, index_size);
|
||||
// register result is trashed by next load, let's use it as temporary register
|
||||
__ get_cache_index_at_bcp(tmp, result, 1, index_size);
|
||||
__ load_resolved_reference_at_index(result, tmp);
|
||||
__ bnez(result, resolved);
|
||||
|
||||
@@ -1695,8 +1702,15 @@ void TemplateTable::branch(bool is_jsr, bool is_wide)
|
||||
|
||||
// load branch displacement
|
||||
if (!is_wide) {
|
||||
__ lhu(x12, at_bcp(1));
|
||||
__ revb_h_h(x12, x12); // reverse bytes in half-word and sign-extend
|
||||
if (AvoidUnalignedAccesses) {
|
||||
__ lb(x12, at_bcp(1));
|
||||
__ lbu(t1, at_bcp(2));
|
||||
__ slli(x12, x12, 8);
|
||||
__ add(x12, x12, t1);
|
||||
} else {
|
||||
__ lhu(x12, at_bcp(1));
|
||||
__ revb_h_h(x12, x12); // reverse bytes in half-word and sign-extend
|
||||
}
|
||||
} else {
|
||||
__ lwu(x12, at_bcp(1));
|
||||
__ revb_w_w(x12, x12); // reverse bytes in word and sign-extend
|
||||
@@ -2099,7 +2113,7 @@ void TemplateTable::fast_binaryswitch() {
|
||||
// else [i = h]
|
||||
// Convert array[h].match to native byte-ordering before compare
|
||||
__ shadd(temp, h, array, temp, 3);
|
||||
__ ld(temp, Address(temp, 0));
|
||||
__ lwu(temp, Address(temp, 0));
|
||||
__ revb_w_w(temp, temp); // reverse bytes in word (32bit) and sign-extend
|
||||
|
||||
Label L_done, L_greater;
|
||||
@@ -2122,7 +2136,7 @@ void TemplateTable::fast_binaryswitch() {
|
||||
Label default_case;
|
||||
// Convert array[i].match to native byte-ordering before compare
|
||||
__ shadd(temp, i, array, temp, 3);
|
||||
__ ld(temp, Address(temp, 0));
|
||||
__ lwu(temp, Address(temp, 0));
|
||||
__ revb_w_w(temp, temp); // reverse bytes in word (32bit) and sign-extend
|
||||
__ bne(key, temp, default_case);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2023, Rivos Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -32,10 +33,18 @@
|
||||
|
||||
#include OS_HEADER_INLINE(os)
|
||||
|
||||
const char* VM_Version::_uarch = "";
|
||||
const char* VM_Version::_vm_mode = "";
|
||||
uint32_t VM_Version::_initial_vector_length = 0;
|
||||
|
||||
#define DEF_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \
|
||||
VM_Version::NAME##RVFeatureValue VM_Version::NAME(PRETTY, BIT, FSTRING);
|
||||
RV_FEATURE_FLAGS(DEF_RV_FEATURE)
|
||||
|
||||
#define ADD_RV_FEATURE_IN_LIST(NAME, PRETTY, BIT, FSTRING, FLAGF) \
|
||||
&VM_Version::NAME,
|
||||
VM_Version::RVFeatureValue* VM_Version::_feature_list[] = {
|
||||
RV_FEATURE_FLAGS(ADD_RV_FEATURE_IN_LIST)
|
||||
nullptr};
|
||||
|
||||
void VM_Version::initialize() {
|
||||
_supports_cx8 = true;
|
||||
_supports_atomic_getset4 = true;
|
||||
@@ -43,13 +52,14 @@ void VM_Version::initialize() {
|
||||
_supports_atomic_getset8 = true;
|
||||
_supports_atomic_getadd8 = true;
|
||||
|
||||
get_os_cpu_info();
|
||||
setup_cpu_available_features();
|
||||
|
||||
// check if satp.mode is supported, currently supports up to SV48(RV64)
|
||||
if (get_satp_mode() > VM_SV48) {
|
||||
if (satp_mode.value() > VM_SV48 || satp_mode.value() < VM_MBARE) {
|
||||
vm_exit_during_initialization(
|
||||
err_msg("Unsupported satp mode: %s. Only satp modes up to sv48 are supported for now.",
|
||||
_vm_mode));
|
||||
err_msg(
|
||||
"Unsupported satp mode: SV%d. Only satp modes up to sv48 are supported for now.",
|
||||
(int)satp_mode.value()));
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(UseFMA)) {
|
||||
@@ -111,28 +121,36 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UseCRC32CIntrinsics, false);
|
||||
}
|
||||
|
||||
if (UseMD5Intrinsics) {
|
||||
warning("MD5 intrinsics are not available on this CPU.");
|
||||
FLAG_SET_DEFAULT(UseMD5Intrinsics, false);
|
||||
if (UseVectorizedMismatchIntrinsic) {
|
||||
warning("VectorizedMismatch intrinsic is not available on this CPU.");
|
||||
FLAG_SET_DEFAULT(UseVectorizedMismatchIntrinsic, false);
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(UseMD5Intrinsics)) {
|
||||
FLAG_SET_DEFAULT(UseMD5Intrinsics, true);
|
||||
}
|
||||
|
||||
if (UseRVV) {
|
||||
if (!(_features & CPU_V)) {
|
||||
if (!ext_V.enabled()) {
|
||||
warning("RVV is not supported on this CPU");
|
||||
FLAG_SET_DEFAULT(UseRVV, false);
|
||||
} else {
|
||||
// read vector length from vector CSR vlenb
|
||||
_initial_vector_length = get_current_vector_length();
|
||||
_initial_vector_length = cpu_vector_length();
|
||||
}
|
||||
}
|
||||
|
||||
if (UseRVC && !(_features & CPU_C)) {
|
||||
if (UseRVC && !ext_C.enabled()) {
|
||||
warning("RVC is not supported on this CPU");
|
||||
FLAG_SET_DEFAULT(UseRVC, false);
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) {
|
||||
FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
|
||||
if (unaligned_access.value() != MISALIGNED_FAST) {
|
||||
FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true);
|
||||
} else {
|
||||
FLAG_SET_DEFAULT(AvoidUnalignedAccesses, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (UseZbb) {
|
||||
@@ -143,16 +161,6 @@ void VM_Version::initialize() {
|
||||
FLAG_SET_DEFAULT(UsePopCountInstruction, false);
|
||||
}
|
||||
|
||||
char buf[512];
|
||||
buf[0] = '\0';
|
||||
if (_uarch != NULL && strcmp(_uarch, "") != 0) snprintf(buf, sizeof(buf), "%s,", _uarch);
|
||||
strcat(buf, "rv64");
|
||||
#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) if (_features & CPU_##id) strcat(buf, name);
|
||||
CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
|
||||
#undef ADD_FEATURE_IF_SUPPORTED
|
||||
|
||||
_features_string = os::strdup(buf);
|
||||
|
||||
#ifdef COMPILER2
|
||||
c2_initialize();
|
||||
#endif // COMPILER2
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2023, Rivos Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -30,53 +31,174 @@
|
||||
#include "runtime/abstract_vm_version.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/globals_extension.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/sizes.hpp"
|
||||
|
||||
class RiscvHwprobe;
|
||||
|
||||
class VM_Version : public Abstract_VM_Version {
|
||||
friend RiscvHwprobe;
|
||||
private:
|
||||
class RVFeatureValue {
|
||||
const char* const _pretty;
|
||||
const bool _feature_string;
|
||||
const uint64_t _feature_bit;
|
||||
bool _enabled;
|
||||
int64_t _value;
|
||||
public:
|
||||
RVFeatureValue(const char* pretty, int bit_num, bool fstring) :
|
||||
_pretty(pretty), _feature_string(fstring), _feature_bit(nth_bit(bit_num)),
|
||||
_enabled(false), _value(-1) {
|
||||
}
|
||||
void enable_feature(int64_t value = 0) {
|
||||
_enabled = true;
|
||||
_value = value;
|
||||
}
|
||||
const char* const pretty() { return _pretty; }
|
||||
const uint64_t feature_bit() { return _feature_bit; }
|
||||
const bool feature_string() { return _feature_string; }
|
||||
bool enabled() { return _enabled; }
|
||||
int64_t value() { return _value; }
|
||||
virtual void update_flag() = 0;
|
||||
};
|
||||
|
||||
#define UPDATE_DEFAULT(flag) \
|
||||
void update_flag() { \
|
||||
assert(enabled(), "Must be."); \
|
||||
if (FLAG_IS_DEFAULT(flag)) { \
|
||||
FLAG_SET_DEFAULT(flag, true); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define NO_UPDATE_DEFAULT \
|
||||
void update_flag() {} \
|
||||
|
||||
// Frozen standard extensions
|
||||
// I RV64I
|
||||
// M Integer Multiplication and Division
|
||||
// A Atomic Instructions
|
||||
// F Single-Precision Floating-Point
|
||||
// D Single-Precision Floating-Point
|
||||
// (G = M + A + F + D)
|
||||
// Q Quad-Precision Floating-Point
|
||||
// C Compressed Instructions
|
||||
// H Hypervisor
|
||||
//
|
||||
// Others, open and non-standard
|
||||
// V Vector
|
||||
//
|
||||
// Cache Management Operations
|
||||
// Zicbom Cache Block Management Operations
|
||||
// Zicboz Cache Block Zero Operations
|
||||
// Zicbop Cache Block Prefetch Operations
|
||||
//
|
||||
// Bit-manipulation
|
||||
// Zba Address generation instructions
|
||||
// Zbb Basic bit-manipulation
|
||||
// Zbc Carry-less multiplication
|
||||
// Zbs Single-bit instructions
|
||||
//
|
||||
// Zicsr Control and Status Register (CSR) Instructions
|
||||
// Zifencei Instruction-Fetch Fence
|
||||
// Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space.
|
||||
// Zihintpause Pause instruction HINT
|
||||
//
|
||||
// Other features and settings
|
||||
// mvendorid Manufactory JEDEC id encoded, ISA vol 2 3.1.2..
|
||||
// marchid Id for microarch. Mvendorid plus marchid uniquely identify the microarch.
|
||||
// mimpid A unique encoding of the version of the processor implementation.
|
||||
// unaligned_access Unaligned memory accesses (unknown, unspported, emulated, slow, firmware, fast)
|
||||
// satp mode SATP bits (number of virtual addr bits) mbare, sv39, sv48, sv57, sv64
|
||||
|
||||
#define RV_NO_FLAG_BIT (BitsPerWord+1) // nth_bit will return 0 on values larger than BitsPerWord
|
||||
|
||||
// declaration name , extension name, bit pos ,in str, mapped flag)
|
||||
#define RV_FEATURE_FLAGS(decl) \
|
||||
decl(ext_I , "i" , ('I' - 'A'), true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_M , "m" , ('M' - 'A'), true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_A , "a" , ('A' - 'A'), true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_F , "f" , ('F' - 'A'), true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_D , "d" , ('D' - 'A'), true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_C , "c" , ('C' - 'A'), true , UPDATE_DEFAULT(UseRVC)) \
|
||||
decl(ext_Q , "q" , ('Q' - 'A'), true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_H , "h" , ('H' - 'A'), true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_V , "v" , ('V' - 'A'), true , UPDATE_DEFAULT(UseRVV)) \
|
||||
decl(ext_Zicbom , "Zicbom" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zicboz , "Zicboz" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zicbop , "Zicbop" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zba , "Zba" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZba)) \
|
||||
decl(ext_Zbb , "Zbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbb)) \
|
||||
decl(ext_Zbc , "Zbc" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zbs , "Zbs" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZbs)) \
|
||||
decl(ext_Zicsr , "Zicsr" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zifencei , "Zifencei" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zic64b , "Zic64b" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(ext_Zihintpause , "Zihintpause" , RV_NO_FLAG_BIT, true , NO_UPDATE_DEFAULT) \
|
||||
decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
decl(unaligned_access, "Unaligned" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
decl(satp_mode , "SATP" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \
|
||||
|
||||
#define DECLARE_RV_FEATURE(NAME, PRETTY, BIT, FSTRING, FLAGF) \
|
||||
struct NAME##RVFeatureValue : public RVFeatureValue { \
|
||||
NAME##RVFeatureValue(const char* pretty, int bit, bool fstring) : \
|
||||
RVFeatureValue(pretty, bit, fstring) {} \
|
||||
FLAGF; \
|
||||
}; \
|
||||
static NAME##RVFeatureValue NAME; \
|
||||
|
||||
RV_FEATURE_FLAGS(DECLARE_RV_FEATURE)
|
||||
#undef DECLARE_RV_FEATURE
|
||||
|
||||
// VM modes (satp.mode) privileged ISA 1.10
|
||||
enum VM_MODE : int {
|
||||
VM_NOTSET = -1,
|
||||
VM_MBARE = 0,
|
||||
VM_SV39 = 39,
|
||||
VM_SV48 = 48,
|
||||
VM_SV57 = 57,
|
||||
VM_SV64 = 64
|
||||
};
|
||||
|
||||
static VM_MODE parse_satp_mode(const char* vm_mode);
|
||||
|
||||
// Values from riscv_hwprobe()
|
||||
enum UNALIGNED_ACCESS : int {
|
||||
MISALIGNED_UNKNOWN = 0,
|
||||
MISALIGNED_EMULATED = 1,
|
||||
MISALIGNED_SLOW = 2,
|
||||
MISALIGNED_FAST = 3,
|
||||
MISALIGNED_UNSUPPORTED = 4
|
||||
};
|
||||
|
||||
// Null terminated list
|
||||
static RVFeatureValue* _feature_list[];
|
||||
|
||||
// Enables features in _feature_list
|
||||
static void setup_cpu_available_features();
|
||||
// Helper for specific queries
|
||||
static void os_aux_features();
|
||||
static char* os_uarch_additional_features();
|
||||
static void vendor_features();
|
||||
// Vendors specific features
|
||||
static void rivos_features();
|
||||
|
||||
// Determine vector length iff ext_V/UseRVV
|
||||
static uint32_t cpu_vector_length();
|
||||
static uint32_t _initial_vector_length;
|
||||
|
||||
#ifdef COMPILER2
|
||||
private:
|
||||
static void c2_initialize();
|
||||
#endif // COMPILER2
|
||||
|
||||
// VM modes (satp.mode) privileged ISA 1.10
|
||||
enum VM_MODE {
|
||||
VM_MBARE = 0,
|
||||
VM_SV39 = 8,
|
||||
VM_SV48 = 9,
|
||||
VM_SV57 = 10,
|
||||
VM_SV64 = 11
|
||||
};
|
||||
|
||||
protected:
|
||||
static const char* _uarch;
|
||||
static const char* _vm_mode;
|
||||
static uint32_t _initial_vector_length;
|
||||
static void get_os_cpu_info();
|
||||
static uint32_t get_current_vector_length();
|
||||
static VM_MODE get_satp_mode();
|
||||
|
||||
public:
|
||||
public:
|
||||
// Initialization
|
||||
static void initialize();
|
||||
static void initialize_cpu_information();
|
||||
|
||||
constexpr static bool supports_stack_watermark_barrier() { return true; }
|
||||
|
||||
enum Feature_Flag {
|
||||
#define CPU_FEATURE_FLAGS(decl) \
|
||||
decl(I, "i", 8) \
|
||||
decl(M, "m", 12) \
|
||||
decl(A, "a", 0) \
|
||||
decl(F, "f", 5) \
|
||||
decl(D, "d", 3) \
|
||||
decl(C, "c", 2) \
|
||||
decl(V, "v", 21)
|
||||
|
||||
#define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1 << bit),
|
||||
CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG)
|
||||
#undef DECLARE_CPU_FEATURE_FLAG
|
||||
};
|
||||
|
||||
static void initialize_cpu_information(void);
|
||||
};
|
||||
|
||||
#endif // CPU_RISCV_VM_VERSION_RISCV_HPP
|
||||
|
||||
@@ -787,7 +787,7 @@ void VM_Version::get_processor_features() {
|
||||
_has_intel_jcc_erratum = IntelJccErratumMitigation;
|
||||
}
|
||||
|
||||
char buf[512];
|
||||
char buf[1024];
|
||||
int res = jio_snprintf(
|
||||
buf, sizeof(buf),
|
||||
"(%u cores per cpu, %u threads per core) family %d model %d stepping %d microcode 0x%x",
|
||||
|
||||
@@ -8195,9 +8195,9 @@ instruct vmasked_load64(vec dst, memory mem, kReg mask) %{
|
||||
ins_pipe( pipe_slow );
|
||||
%}
|
||||
|
||||
instruct vmask_gen(kReg dst, rRegL len, rRegL temp) %{
|
||||
instruct vmask_gen(kReg dst, rRegL len, rRegL temp, rFlagsReg cr) %{
|
||||
match(Set dst (VectorMaskGen len));
|
||||
effect(TEMP temp);
|
||||
effect(TEMP temp, KILL cr);
|
||||
format %{ "vector_mask_gen32 $dst, $len \t! vector mask generator" %}
|
||||
ins_encode %{
|
||||
__ genmask($dst$$KRegister, $len$$Register, $temp$$Register);
|
||||
|
||||
@@ -98,6 +98,15 @@
|
||||
"to disable both the override and the printouts." \
|
||||
"See prctl(PR_SET_TIMERSLACK) for more info.") \
|
||||
\
|
||||
product(bool, THPStackMitigation, true, DIAGNOSTIC, \
|
||||
"If THPs are unconditionally enabled on the system (mode " \
|
||||
"\"always\"), the JVM will prevent THP from forming in " \
|
||||
"thread stacks. When disabled, the absence of this mitigation"\
|
||||
"allows THPs to form in thread stacks.") \
|
||||
\
|
||||
develop(bool, DelayThreadStartALot, false, \
|
||||
"Artificially delay thread starts randomly for testing.") \
|
||||
\
|
||||
|
||||
|
||||
// end of RUNTIME_OS_FLAGS
|
||||
|
||||
241
src/hotspot/os/linux/hugepages.cpp
Normal file
241
src/hotspot/os/linux/hugepages.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2023, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "hugepages.hpp"
|
||||
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
StaticHugePageSupport::StaticHugePageSupport() :
|
||||
_initialized(false), _pagesizes(), _default_hugepage_size(SIZE_MAX), _inconsistent(false) {}
|
||||
|
||||
os::PageSizes StaticHugePageSupport::pagesizes() const {
|
||||
assert(_initialized, "Not initialized");
|
||||
return _pagesizes;
|
||||
}
|
||||
|
||||
size_t StaticHugePageSupport::default_hugepage_size() const {
|
||||
assert(_initialized, "Not initialized");
|
||||
return _default_hugepage_size;
|
||||
}
|
||||
|
||||
// Scan /proc/meminfo and return value of Hugepagesize
|
||||
static size_t scan_default_hugepagesize() {
|
||||
size_t pagesize = 0;
|
||||
|
||||
// large_page_size on Linux is used to round up heap size. x86 uses either
|
||||
// 2M or 4M page, depending on whether PAE (Physical Address Extensions)
|
||||
// mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
|
||||
// page as large as 1G.
|
||||
//
|
||||
// Here we try to figure out page size by parsing /proc/meminfo and looking
|
||||
// for a line with the following format:
|
||||
// Hugepagesize: 2048 kB
|
||||
//
|
||||
// If we can't determine the value (e.g. /proc is not mounted, or the text
|
||||
// format has been changed), we'll set largest page size to 0
|
||||
|
||||
FILE *fp = os::fopen("/proc/meminfo", "r");
|
||||
if (fp) {
|
||||
while (!feof(fp)) {
|
||||
int x = 0;
|
||||
char buf[16];
|
||||
if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
|
||||
if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
|
||||
pagesize = x * K;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// skip to next line
|
||||
for (;;) {
|
||||
int ch = fgetc(fp);
|
||||
if (ch == EOF || ch == (int)'\n') break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return pagesize;
|
||||
}
|
||||
|
||||
// Given a file that contains a single (integral) number, return that number in (*out) and true;
|
||||
// in case of an error, return false.
|
||||
static bool read_number_file(const char* file, size_t* out) {
|
||||
FILE* f = ::fopen(file, "r");
|
||||
bool rc = false;
|
||||
if (f != nullptr) {
|
||||
uint64_t i = 0;
|
||||
if (::fscanf(f, SIZE_FORMAT, out) == 1) {
|
||||
rc = true;
|
||||
}
|
||||
::fclose(f);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const char* const sys_hugepages = "/sys/kernel/mm/hugepages";
|
||||
|
||||
// Scan all directories in /sys/kernel/mm/hugepages/hugepages-xxxx
|
||||
// to discover the available page sizes
|
||||
static os::PageSizes scan_hugepages() {
|
||||
|
||||
os::PageSizes pagesizes;
|
||||
|
||||
DIR* dir = opendir(sys_hugepages);
|
||||
|
||||
if (dir != nullptr) {
|
||||
struct dirent *entry;
|
||||
size_t pagesize;
|
||||
while ((entry = readdir(dir)) != nullptr) {
|
||||
if (entry->d_type == DT_DIR &&
|
||||
sscanf(entry->d_name, "hugepages-%zukB", &pagesize) == 1) {
|
||||
// The kernel is using kB, hotspot uses bytes
|
||||
// Add each found Large Page Size to page_sizes
|
||||
pagesize *= K;
|
||||
pagesizes.add(pagesize);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
return pagesizes;
|
||||
}
|
||||
|
||||
void StaticHugePageSupport::print_on(outputStream* os) {
|
||||
if (_initialized) {
|
||||
os->print_cr("Static hugepage support:");
|
||||
for (size_t s = _pagesizes.smallest(); s != 0; s = _pagesizes.next_larger(s)) {
|
||||
os->print_cr(" hugepage size: " EXACTFMT, EXACTFMTARGS(s));
|
||||
}
|
||||
os->print_cr(" default hugepage size: " EXACTFMT, EXACTFMTARGS(_default_hugepage_size));
|
||||
} else {
|
||||
os->print_cr(" unknown.");
|
||||
}
|
||||
if (_inconsistent) {
|
||||
os->print_cr(" Support inconsistent. JVM will not use static hugepages.");
|
||||
}
|
||||
}
|
||||
|
||||
void StaticHugePageSupport::scan_os() {
|
||||
_default_hugepage_size = scan_default_hugepagesize();
|
||||
if (_default_hugepage_size > 0) {
|
||||
_pagesizes = scan_hugepages();
|
||||
// See https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt: /proc/meminfo should match
|
||||
// /sys/kernel/mm/hugepages/hugepages-xxxx. However, we may run on a broken kernel (e.g. on WSL)
|
||||
// that only exposes /proc/meminfo but not /sys/kernel/mm/hugepages. In that case, we are not
|
||||
// sure about the state of hugepage support by the kernel, so we won't use static hugepages.
|
||||
if (!_pagesizes.contains(_default_hugepage_size)) {
|
||||
log_info(pagesize)("Unexpected configuration: default pagesize (" SIZE_FORMAT ") "
|
||||
"has no associated directory in /sys/kernel/mm/hugepages..", _default_hugepage_size);
|
||||
_inconsistent = true;
|
||||
}
|
||||
}
|
||||
_initialized = true;
|
||||
LogTarget(Info, pagesize) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
print_on(&ls);
|
||||
}
|
||||
}
|
||||
|
||||
THPSupport::THPSupport() :
|
||||
_initialized(false), _mode(THPMode::never), _pagesize(SIZE_MAX) {}
|
||||
|
||||
|
||||
THPMode THPSupport::mode() const {
|
||||
assert(_initialized, "Not initialized");
|
||||
return _mode;
|
||||
}
|
||||
|
||||
size_t THPSupport::pagesize() const {
|
||||
assert(_initialized, "Not initialized");
|
||||
return _pagesize;
|
||||
}
|
||||
|
||||
void THPSupport::scan_os() {
|
||||
// Scan /sys/kernel/mm/transparent_hugepage/enabled
|
||||
// see mm/huge_memory.c
|
||||
_mode = THPMode::never;
|
||||
const char* filename = "/sys/kernel/mm/transparent_hugepage/enabled";
|
||||
FILE* f = ::fopen(filename, "r");
|
||||
if (f != nullptr) {
|
||||
char buf[64];
|
||||
char* s = fgets(buf, sizeof(buf), f);
|
||||
assert(s == buf, "Should have worked");
|
||||
if (::strstr(buf, "[madvise]") != nullptr) {
|
||||
_mode = THPMode::madvise;
|
||||
} else if (::strstr(buf, "[always]") != nullptr) {
|
||||
_mode = THPMode::always;
|
||||
} else {
|
||||
assert(::strstr(buf, "[never]") != nullptr, "Weird content of %s: %s", filename, buf);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
// Scan large page size for THP from hpage_pmd_size
|
||||
_pagesize = 0;
|
||||
if (read_number_file("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", &_pagesize)) {
|
||||
assert(_pagesize > 0, "Expected");
|
||||
}
|
||||
_initialized = true;
|
||||
|
||||
LogTarget(Info, pagesize) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
print_on(&ls);
|
||||
}
|
||||
}
|
||||
|
||||
void THPSupport::print_on(outputStream* os) {
|
||||
if (_initialized) {
|
||||
os->print_cr("Transparent hugepage (THP) support:");
|
||||
os->print_cr(" THP mode: %s",
|
||||
(_mode == THPMode::always ? "always" : (_mode == THPMode::never ? "never" : "madvise")));
|
||||
os->print_cr(" THP pagesize: " EXACTFMT, EXACTFMTARGS(_pagesize));
|
||||
} else {
|
||||
os->print_cr(" unknown.");
|
||||
}
|
||||
}
|
||||
|
||||
StaticHugePageSupport HugePages::_static_hugepage_support;
|
||||
THPSupport HugePages::_thp_support;
|
||||
|
||||
void HugePages::initialize() {
|
||||
_static_hugepage_support.scan_os();
|
||||
_thp_support.scan_os();
|
||||
}
|
||||
|
||||
void HugePages::print_on(outputStream* os) {
|
||||
_static_hugepage_support.print_on(os);
|
||||
_thp_support.print_on(os);
|
||||
}
|
||||
115
src/hotspot/os/linux/hugepages.hpp
Normal file
115
src/hotspot/os/linux/hugepages.hpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2023, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_LINUX_HUGEPAGES_HPP
|
||||
#define OS_LINUX_HUGEPAGES_HPP
|
||||
|
||||
#include "memory/allStatic.hpp"
|
||||
#include "runtime/os.hpp" // for os::PageSizes
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
class outputStream;
|
||||
|
||||
// Header contains the interface that reads OS information about
|
||||
// available hugepage support:
|
||||
// - class StaticHugePageSupport - about static (non-THP) hugepages
|
||||
// - class THPSupport - about transparent huge pages
|
||||
// and:
|
||||
// - class HugePages - a static umbrella wrapper
|
||||
|
||||
// Information about static (non-thp) hugepages
|
||||
class StaticHugePageSupport {
|
||||
bool _initialized;
|
||||
|
||||
// All supported hugepage sizes (sizes for which entries exist
|
||||
// in /sys/kernel/mm/hugepages/hugepage-xxx)
|
||||
os::PageSizes _pagesizes;
|
||||
|
||||
// Contains the default hugepage. The "default hugepage size" is the one that
|
||||
// - is marked in /proc/meminfo as "Hugepagesize"
|
||||
// - is the size one gets when using mmap(MAP_HUGETLB) when omitting size specifiers like MAP_HUGE_SHIFT)
|
||||
size_t _default_hugepage_size;
|
||||
|
||||
// If true, the kernel support for hugepages is inconsistent
|
||||
bool _inconsistent;
|
||||
|
||||
public:
|
||||
StaticHugePageSupport();
|
||||
|
||||
void scan_os();
|
||||
|
||||
os::PageSizes pagesizes() const;
|
||||
size_t default_hugepage_size() const;
|
||||
void print_on(outputStream* os);
|
||||
|
||||
bool inconsistent() const { return _inconsistent; }
|
||||
};
|
||||
|
||||
enum class THPMode { always, never, madvise };
|
||||
|
||||
// 2) for transparent hugepages
|
||||
class THPSupport {
|
||||
bool _initialized;
|
||||
|
||||
// See /sys/kernel/mm/transparent_hugepages/enabled
|
||||
THPMode _mode;
|
||||
|
||||
// Contains the THP page size
|
||||
size_t _pagesize;
|
||||
|
||||
public:
|
||||
|
||||
THPSupport();
|
||||
|
||||
// Queries the OS, fills in object
|
||||
void scan_os();
|
||||
|
||||
THPMode mode() const;
|
||||
size_t pagesize() const;
|
||||
void print_on(outputStream* os);
|
||||
};
|
||||
|
||||
// Umbrella static interface
|
||||
class HugePages : public AllStatic {
|
||||
|
||||
static StaticHugePageSupport _static_hugepage_support;
|
||||
static THPSupport _thp_support;
|
||||
|
||||
public:
|
||||
|
||||
static const StaticHugePageSupport& static_info() { return _static_hugepage_support; }
|
||||
static const THPSupport& thp_info() { return _thp_support; }
|
||||
|
||||
static size_t default_static_hugepage_size() { return _static_hugepage_support.default_hugepage_size(); }
|
||||
static bool supports_static_hugepages() { return default_static_hugepage_size() > 0 && !_static_hugepage_support.inconsistent(); }
|
||||
static THPMode thp_mode() { return _thp_support.mode(); }
|
||||
static bool supports_thp() { return thp_mode() == THPMode::madvise || thp_mode() == THPMode::always; }
|
||||
static size_t thp_pagesize() { return _thp_support.pagesize(); }
|
||||
|
||||
static void initialize();
|
||||
static void print_on(outputStream* os);
|
||||
};
|
||||
|
||||
#endif // OS_LINUX_HUGEPAGES_HPP
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "hugepages.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvmtifiles/jvmti.h"
|
||||
#include "logging/log.hpp"
|
||||
@@ -166,7 +167,6 @@ int os::Linux::_page_size = -1;
|
||||
bool os::Linux::_supports_fast_thread_cpu_time = false;
|
||||
const char * os::Linux::_libc_version = NULL;
|
||||
const char * os::Linux::_libpthread_version = NULL;
|
||||
size_t os::Linux::_default_large_page_size = 0;
|
||||
|
||||
#ifdef __GLIBC__
|
||||
os::Linux::mallinfo_func_t os::Linux::_mallinfo = NULL;
|
||||
@@ -721,6 +721,10 @@ static void *thread_native_entry(Thread *thread) {
|
||||
|
||||
assert(osthread->pthread_id() != 0, "pthread_id was not set as expected");
|
||||
|
||||
if (DelayThreadStartALot) {
|
||||
os::naked_short_sleep(100);
|
||||
}
|
||||
|
||||
// call one more level start routine
|
||||
thread->call_run();
|
||||
|
||||
@@ -857,6 +861,7 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
// Calculate stack size if it's not specified by caller.
|
||||
size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);
|
||||
size_t guard_size = os::Linux::default_guard_size(thr_type);
|
||||
|
||||
// Configure glibc guard page. Must happen before calling
|
||||
// get_static_tls_area_size(), which uses the guard_size.
|
||||
pthread_attr_setguardsize(&attr, guard_size);
|
||||
@@ -877,13 +882,16 @@ bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
}
|
||||
assert(is_aligned(stack_size, os::vm_page_size()), "stack_size not aligned");
|
||||
|
||||
// Add an additional page to the stack size to reduce its chances of getting large page aligned
|
||||
// so that the stack does not get backed by a transparent huge page.
|
||||
size_t default_large_page_size = os::Linux::default_large_page_size();
|
||||
if (default_large_page_size != 0 &&
|
||||
stack_size >= default_large_page_size &&
|
||||
is_aligned(stack_size, default_large_page_size)) {
|
||||
stack_size += os::vm_page_size();
|
||||
if (THPStackMitigation) {
|
||||
// In addition to the glibc guard page that prevents inter-thread-stack hugepage
|
||||
// coalescing (see comment in os::Linux::default_guard_size()), we also make
|
||||
// sure the stack size itself is not huge-page-size aligned; that makes it much
|
||||
// more likely for thread stack boundaries to be unaligned as well and hence
|
||||
// protects thread stacks from being targeted by khugepaged.
|
||||
if (HugePages::thp_pagesize() > 0 &&
|
||||
is_aligned(stack_size, HugePages::thp_pagesize())) {
|
||||
stack_size += os::vm_page_size();
|
||||
}
|
||||
}
|
||||
|
||||
int status = pthread_attr_setstacksize(&attr, stack_size);
|
||||
@@ -1791,11 +1799,11 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
|
||||
static Elf32_Half running_arch_code=EM_SH;
|
||||
#elif (defined RISCV)
|
||||
static Elf32_Half running_arch_code=EM_RISCV;
|
||||
#elif (defined LOONGARCH)
|
||||
#elif (defined LOONGARCH64)
|
||||
static Elf32_Half running_arch_code=EM_LOONGARCH;
|
||||
#else
|
||||
#error Method os::dll_load requires that one of following is defined:\
|
||||
AARCH64, ALPHA, ARM, AMD64, IA32, IA64, LOONGARCH, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, RISCV, S390, SH, __sparc
|
||||
AARCH64, ALPHA, ARM, AMD64, IA32, IA64, LOONGARCH64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, RISCV, S390, SH, __sparc
|
||||
#endif
|
||||
|
||||
// Identify compatibility class for VM's architecture and library's architecture
|
||||
@@ -3139,6 +3147,27 @@ bool os::Linux::libnuma_init() {
|
||||
}
|
||||
|
||||
size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
|
||||
|
||||
if (THPStackMitigation) {
|
||||
// If THPs are unconditionally enabled, the following scenario can lead to huge RSS
|
||||
// - parent thread spawns, in quick succession, multiple child threads
|
||||
// - child threads are slow to start
|
||||
// - thread stacks of future child threads are adjacent and get merged into one large VMA
|
||||
// by the kernel, and subsequently transformed into huge pages by khugepaged
|
||||
// - child threads come up, place JVM guard pages, thus splinter the large VMA, splinter
|
||||
// the huge pages into many (still paged-in) small pages.
|
||||
// The result of that sequence are thread stacks that are fully paged-in even though the
|
||||
// threads did not even start yet.
|
||||
// We prevent that by letting the glibc allocate a guard page, which causes a VMA with different
|
||||
// permission bits to separate two ajacent thread stacks and therefore prevent merging stacks
|
||||
// into one VMA.
|
||||
//
|
||||
// Yes, this means we have two guard sections - the glibc and the JVM one - per thread. But the
|
||||
// cost for that one extra protected page is dwarfed from a large win in performance and memory
|
||||
// that avoiding interference by khugepaged buys us.
|
||||
return os::vm_page_size();
|
||||
}
|
||||
|
||||
// Creating guard page is very expensive. Java thread has HotSpot
|
||||
// guard pages, only enable glibc guard page for non-Java threads.
|
||||
// (Remember: compiler thread is a Java thread, too!)
|
||||
@@ -3618,7 +3647,7 @@ bool os::Linux::transparent_huge_pages_sanity_check(bool warn,
|
||||
}
|
||||
|
||||
int os::Linux::hugetlbfs_page_size_flag(size_t page_size) {
|
||||
if (page_size != default_large_page_size()) {
|
||||
if (page_size != HugePages::default_static_hugepage_size()) {
|
||||
return (exact_log2(page_size) << MAP_HUGE_SHIFT);
|
||||
}
|
||||
return 0;
|
||||
@@ -3726,79 +3755,6 @@ static void set_coredump_filter(CoredumpFilterBit bit) {
|
||||
|
||||
static size_t _large_page_size = 0;
|
||||
|
||||
static size_t scan_default_large_page_size() {
|
||||
size_t default_large_page_size = 0;
|
||||
|
||||
// large_page_size on Linux is used to round up heap size. x86 uses either
|
||||
// 2M or 4M page, depending on whether PAE (Physical Address Extensions)
|
||||
// mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
|
||||
// page as large as 1G.
|
||||
//
|
||||
// Here we try to figure out page size by parsing /proc/meminfo and looking
|
||||
// for a line with the following format:
|
||||
// Hugepagesize: 2048 kB
|
||||
//
|
||||
// If we can't determine the value (e.g. /proc is not mounted, or the text
|
||||
// format has been changed), we'll set largest page size to 0
|
||||
|
||||
FILE *fp = fopen("/proc/meminfo", "r");
|
||||
if (fp) {
|
||||
while (!feof(fp)) {
|
||||
int x = 0;
|
||||
char buf[16];
|
||||
if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
|
||||
if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
|
||||
default_large_page_size = x * K;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// skip to next line
|
||||
for (;;) {
|
||||
int ch = fgetc(fp);
|
||||
if (ch == EOF || ch == (int)'\n') break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return default_large_page_size;
|
||||
}
|
||||
|
||||
static os::PageSizes scan_multiple_page_support() {
|
||||
// Scan /sys/kernel/mm/hugepages
|
||||
// to discover the available page sizes
|
||||
const char* sys_hugepages = "/sys/kernel/mm/hugepages";
|
||||
os::PageSizes page_sizes;
|
||||
|
||||
DIR *dir = opendir(sys_hugepages);
|
||||
|
||||
struct dirent *entry;
|
||||
size_t page_size;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_type == DT_DIR &&
|
||||
sscanf(entry->d_name, "hugepages-%zukB", &page_size) == 1) {
|
||||
// The kernel is using kB, hotspot uses bytes
|
||||
// Add each found Large Page Size to page_sizes
|
||||
page_sizes.add(page_size * K);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
LogTarget(Debug, pagesize) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
ls.print("Large Page sizes: ");
|
||||
page_sizes.print_on(&ls);
|
||||
}
|
||||
|
||||
return page_sizes;
|
||||
}
|
||||
|
||||
size_t os::Linux::default_large_page_size() {
|
||||
return _default_large_page_size;
|
||||
}
|
||||
|
||||
void warn_no_large_pages_configured() {
|
||||
if (!FLAG_IS_DEFAULT(UseLargePages)) {
|
||||
log_warning(pagesize)("UseLargePages disabled, no large pages configured and available on the system.");
|
||||
@@ -3851,10 +3807,44 @@ bool os::Linux::setup_large_page_type(size_t page_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct LargePageInitializationLoggerMark {
|
||||
~LargePageInitializationLoggerMark() {
|
||||
LogTarget(Info, pagesize) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
if (UseLargePages) {
|
||||
ls.print_cr("UseLargePages=1, UseTransparentHugePages=%d, UseHugeTLBFS=%d, UseSHM=%d",
|
||||
UseTransparentHugePages, UseHugeTLBFS, UseSHM);
|
||||
ls.print("Large page support enabled. Usable page sizes: ");
|
||||
os::page_sizes().print_on(&ls);
|
||||
ls.print_cr(". Default large page size: " EXACTFMT ".", EXACTFMTARGS(os::large_page_size()));
|
||||
} else {
|
||||
ls.print("Large page support disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void os::large_page_init() {
|
||||
// Always initialize the default large page size even if large pages are not being used.
|
||||
size_t default_large_page_size = scan_default_large_page_size();
|
||||
os::Linux::_default_large_page_size = default_large_page_size;
|
||||
LargePageInitializationLoggerMark logger;
|
||||
|
||||
// Query OS information first.
|
||||
HugePages::initialize();
|
||||
|
||||
// If THPs are unconditionally enabled (THP mode "always"), khugepaged may attempt to
|
||||
// coalesce small pages in thread stacks to huge pages. That costs a lot of memory and
|
||||
// is usually unwanted for thread stacks. Therefore we attempt to prevent THP formation in
|
||||
// thread stacks unless the user explicitly allowed THP formation by manually disabling
|
||||
// -XX:-THPStackMitigation.
|
||||
if (HugePages::thp_mode() == THPMode::always) {
|
||||
if (THPStackMitigation) {
|
||||
log_info(pagesize)("JVM will attempt to prevent THPs in thread stacks.");
|
||||
} else {
|
||||
log_info(pagesize)("JVM will *not* prevent THPs in thread stacks. This may cause high RSS.");
|
||||
}
|
||||
} else {
|
||||
FLAG_SET_ERGO(THPStackMitigation, false); // Mitigation not needed
|
||||
}
|
||||
|
||||
// 1) Handle the case where we do not want to use huge pages
|
||||
if (!UseLargePages &&
|
||||
@@ -3874,67 +3864,77 @@ void os::large_page_init() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2) check if large pages are configured
|
||||
if (default_large_page_size == 0) {
|
||||
// No large pages configured, return.
|
||||
warn_no_large_pages_configured();
|
||||
UseLargePages = false;
|
||||
UseTransparentHugePages = false;
|
||||
UseHugeTLBFS = false;
|
||||
UseSHM = false;
|
||||
// 2) check if the OS supports THPs resp. static hugepages.
|
||||
if (UseTransparentHugePages && !HugePages::supports_thp()) {
|
||||
if (!FLAG_IS_DEFAULT(UseTransparentHugePages)) {
|
||||
log_warning(pagesize)("UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system.");
|
||||
}
|
||||
UseLargePages = UseTransparentHugePages = UseHugeTLBFS = UseSHM = false;
|
||||
return;
|
||||
}
|
||||
if (!UseTransparentHugePages && !HugePages::supports_static_hugepages()) {
|
||||
warn_no_large_pages_configured();
|
||||
UseLargePages = UseTransparentHugePages = UseHugeTLBFS = UseSHM = false;
|
||||
return;
|
||||
}
|
||||
os::PageSizes all_large_pages = scan_multiple_page_support();
|
||||
|
||||
// 3) Consistency check and post-processing
|
||||
if (UseTransparentHugePages) {
|
||||
// In THP mode:
|
||||
// - os::large_page_size() is the *THP page size*
|
||||
// - os::pagesizes() has two members, the THP page size and the system page size
|
||||
assert(HugePages::supports_thp() && HugePages::thp_pagesize() > 0, "Missing OS info");
|
||||
_large_page_size = HugePages::thp_pagesize();
|
||||
_page_sizes.add(_large_page_size);
|
||||
_page_sizes.add(os::vm_page_size());
|
||||
|
||||
// It is unclear if /sys/kernel/mm/hugepages/ and /proc/meminfo could disagree. Manually
|
||||
// re-add the default page size to the list of page sizes to be sure.
|
||||
all_large_pages.add(default_large_page_size);
|
||||
|
||||
// Check LargePageSizeInBytes matches an available page size and if so set _large_page_size
|
||||
// using LargePageSizeInBytes as the maximum allowed large page size. If LargePageSizeInBytes
|
||||
// doesn't match an available page size set _large_page_size to default_large_page_size
|
||||
// and use it as the maximum.
|
||||
if (FLAG_IS_DEFAULT(LargePageSizeInBytes) ||
|
||||
LargePageSizeInBytes == 0 ||
|
||||
LargePageSizeInBytes == default_large_page_size) {
|
||||
_large_page_size = default_large_page_size;
|
||||
log_info(pagesize)("Using the default large page size: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
} else {
|
||||
if (all_large_pages.contains(LargePageSizeInBytes)) {
|
||||
_large_page_size = LargePageSizeInBytes;
|
||||
log_info(pagesize)("Overriding default large page size (" SIZE_FORMAT "%s) "
|
||||
"using LargePageSizeInBytes: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(default_large_page_size),
|
||||
exact_unit_for_byte_size(default_large_page_size),
|
||||
|
||||
// In static hugepage mode:
|
||||
// - os::large_page_size() is the default static hugepage size (/proc/meminfo "Hugepagesize")
|
||||
// - os::pagesizes() contains all hugepage sizes the kernel supports, regardless whether there
|
||||
// are pages configured in the pool or not (from /sys/kernel/hugepages/hugepage-xxxx ...)
|
||||
os::PageSizes all_large_pages = HugePages::static_info().pagesizes();
|
||||
const size_t default_large_page_size = HugePages::default_static_hugepage_size();
|
||||
|
||||
// 3) Consistency check and post-processing
|
||||
|
||||
// Check LargePageSizeInBytes matches an available page size and if so set _large_page_size
|
||||
// using LargePageSizeInBytes as the maximum allowed large page size. If LargePageSizeInBytes
|
||||
// doesn't match an available page size set _large_page_size to default_large_page_size
|
||||
// and use it as the maximum.
|
||||
if (FLAG_IS_DEFAULT(LargePageSizeInBytes) ||
|
||||
LargePageSizeInBytes == 0 ||
|
||||
LargePageSizeInBytes == default_large_page_size) {
|
||||
_large_page_size = default_large_page_size;
|
||||
log_info(pagesize)("Using the default large page size: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
} else {
|
||||
_large_page_size = default_large_page_size;
|
||||
log_info(pagesize)("LargePageSizeInBytes is not a valid large page size (" SIZE_FORMAT "%s) "
|
||||
"using the default large page size: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(LargePageSizeInBytes),
|
||||
exact_unit_for_byte_size(LargePageSizeInBytes),
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
if (all_large_pages.contains(LargePageSizeInBytes)) {
|
||||
_large_page_size = LargePageSizeInBytes;
|
||||
log_info(pagesize)("Overriding default large page size (" SIZE_FORMAT "%s) "
|
||||
"using LargePageSizeInBytes: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(default_large_page_size),
|
||||
exact_unit_for_byte_size(default_large_page_size),
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
} else {
|
||||
_large_page_size = default_large_page_size;
|
||||
log_info(pagesize)("LargePageSizeInBytes is not a valid large page size (" SIZE_FORMAT "%s) "
|
||||
"using the default large page size: " SIZE_FORMAT "%s",
|
||||
byte_size_in_exact_unit(LargePageSizeInBytes),
|
||||
exact_unit_for_byte_size(LargePageSizeInBytes),
|
||||
byte_size_in_exact_unit(_large_page_size),
|
||||
exact_unit_for_byte_size(_large_page_size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Populate _page_sizes with large page sizes less than or equal to
|
||||
// _large_page_size.
|
||||
for (size_t page_size = _large_page_size; page_size != 0;
|
||||
page_size = all_large_pages.next_smaller(page_size)) {
|
||||
_page_sizes.add(page_size);
|
||||
}
|
||||
|
||||
LogTarget(Info, pagesize) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
ls.print("Usable page sizes: ");
|
||||
_page_sizes.print_on(&ls);
|
||||
// Populate _page_sizes with large page sizes less than or equal to
|
||||
// _large_page_size.
|
||||
for (size_t page_size = _large_page_size; page_size != 0;
|
||||
page_size = all_large_pages.next_smaller(page_size)) {
|
||||
_page_sizes.add(page_size);
|
||||
}
|
||||
}
|
||||
|
||||
// Now determine the type of large pages to use:
|
||||
|
||||
@@ -50,8 +50,6 @@ class Linux {
|
||||
static GrowableArray<int>* _cpu_to_node;
|
||||
static GrowableArray<int>* _nindex_to_node;
|
||||
|
||||
static size_t _default_large_page_size;
|
||||
|
||||
protected:
|
||||
|
||||
static julong _physical_memory;
|
||||
@@ -75,10 +73,6 @@ class Linux {
|
||||
static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }
|
||||
static GrowableArray<int>* nindex_to_node() { return _nindex_to_node; }
|
||||
|
||||
static size_t default_large_page_size();
|
||||
static size_t scan_default_large_page_size();
|
||||
static os::PageSizes scan_multiple_page_support();
|
||||
|
||||
static bool setup_large_page_type(size_t page_size);
|
||||
static bool transparent_huge_pages_sanity_check(bool warn, size_t pages_size);
|
||||
static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
|
||||
|
||||
@@ -33,10 +33,23 @@
|
||||
// Note that memory_order_conservative requires a full barrier after atomic stores.
|
||||
// See https://patchwork.kernel.org/patch/3575821/
|
||||
|
||||
#if defined(__clang_major__)
|
||||
#define FULL_COMPILER_ATOMIC_SUPPORT
|
||||
#elif (__GNUC__ > 13) || ((__GNUC__ == 13) && (__GNUC_MINOR__ >= 2))
|
||||
#define FULL_COMPILER_ATOMIC_SUPPORT
|
||||
#endif
|
||||
|
||||
template<size_t byte_size>
|
||||
struct Atomic::PlatformAdd {
|
||||
template<typename D, typename I>
|
||||
D add_and_fetch(D volatile* dest, I add_value, atomic_memory_order order) const {
|
||||
|
||||
#ifndef FULL_COMPILER_ATOMIC_SUPPORT
|
||||
// If we add add and fetch for sub word and are using older compiler
|
||||
// it must be added here due to not using lib atomic.
|
||||
STATIC_ASSERT(byte_size >= 4);
|
||||
#endif
|
||||
|
||||
if (order != memory_order_relaxed) {
|
||||
FULL_MEM_BARRIER;
|
||||
}
|
||||
@@ -55,12 +68,65 @@ struct Atomic::PlatformAdd {
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef FULL_COMPILER_ATOMIC_SUPPORT
|
||||
template<>
|
||||
template<typename T>
|
||||
inline T Atomic::PlatformCmpxchg<1>::operator()(T volatile* dest __attribute__((unused)),
|
||||
T compare_value,
|
||||
T exchange_value,
|
||||
atomic_memory_order order) const {
|
||||
STATIC_ASSERT(1 == sizeof(T));
|
||||
|
||||
if (order != memory_order_relaxed) {
|
||||
FULL_MEM_BARRIER;
|
||||
}
|
||||
|
||||
uint32_t volatile* aligned_dst = (uint32_t volatile*)(((uintptr_t)dest) & (~((uintptr_t)0x3)));
|
||||
int shift = 8 * (((uintptr_t)dest) - ((uintptr_t)aligned_dst)); // 0, 8, 16, 24
|
||||
|
||||
uint64_t mask = 0xfful << shift; // 0x00000000..FF..
|
||||
uint64_t remask = ~mask; // 0xFFFFFFFF..00..
|
||||
|
||||
uint64_t w_cv = ((uint64_t)(unsigned char)compare_value) << shift; // widen to 64-bit 0x00000000..CC..
|
||||
uint64_t w_ev = ((uint64_t)(unsigned char)exchange_value) << shift; // widen to 64-bit 0x00000000..EE..
|
||||
|
||||
uint64_t old_value;
|
||||
uint64_t rc_temp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"1: lr.w %0, %2 \n\t"
|
||||
" and %1, %0, %5 \n\t" // ignore unrelated bytes and widen to 64-bit 0x00000000..XX..
|
||||
" bne %1, %3, 2f \n\t" // compare 64-bit w_cv
|
||||
" and %1, %0, %6 \n\t" // remove old byte
|
||||
" or %1, %1, %4 \n\t" // add new byte
|
||||
" sc.w %1, %1, %2 \n\t" // store new word
|
||||
" bnez %1, 1b \n\t"
|
||||
"2: \n\t"
|
||||
: /*%0*/"=&r" (old_value), /*%1*/"=&r" (rc_temp), /*%2*/"+A" (*aligned_dst)
|
||||
: /*%3*/"r" (w_cv), /*%4*/"r" (w_ev), /*%5*/"r" (mask), /*%6*/"r" (remask)
|
||||
: "memory" );
|
||||
|
||||
if (order != memory_order_relaxed) {
|
||||
FULL_MEM_BARRIER;
|
||||
}
|
||||
|
||||
return (T)((old_value & mask) >> shift);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<size_t byte_size>
|
||||
template<typename T>
|
||||
inline T Atomic::PlatformXchg<byte_size>::operator()(T volatile* dest,
|
||||
T exchange_value,
|
||||
atomic_memory_order order) const {
|
||||
#ifndef FULL_COMPILER_ATOMIC_SUPPORT
|
||||
// If we add xchg for sub word and are using older compiler
|
||||
// it must be added here due to not using lib atomic.
|
||||
STATIC_ASSERT(byte_size >= 4);
|
||||
#endif
|
||||
|
||||
STATIC_ASSERT(byte_size == sizeof(T));
|
||||
|
||||
if (order != memory_order_relaxed) {
|
||||
FULL_MEM_BARRIER;
|
||||
}
|
||||
@@ -80,6 +146,11 @@ inline T Atomic::PlatformCmpxchg<byte_size>::operator()(T volatile* dest __attri
|
||||
T compare_value,
|
||||
T exchange_value,
|
||||
atomic_memory_order order) const {
|
||||
|
||||
#ifndef FULL_COMPILER_ATOMIC_SUPPORT
|
||||
STATIC_ASSERT(byte_size >= 4);
|
||||
#endif
|
||||
|
||||
STATIC_ASSERT(byte_size == sizeof(T));
|
||||
T value = compare_value;
|
||||
if (order != memory_order_relaxed) {
|
||||
@@ -148,4 +219,6 @@ struct Atomic::PlatformOrderedStore<byte_size, RELEASE_X_FENCE>
|
||||
void operator()(volatile T* p, T v) const { release_store(p, v); OrderAccess::fence(); }
|
||||
};
|
||||
|
||||
#undef FULL_COMPILER_ATOMIC_SUPPORT
|
||||
|
||||
#endif // OS_CPU_LINUX_RISCV_ATOMIC_LINUX_RISCV_HPP
|
||||
|
||||
77
src/hotspot/os_cpu/linux_riscv/riscv_flush_icache.cpp
Normal file
77
src/hotspot/os_cpu/linux_riscv/riscv_flush_icache.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, Rivos Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "riscv_flush_icache.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define check_with_errno(check_type, cond, msg) \
|
||||
do { \
|
||||
int err = errno; \
|
||||
check_type(cond, "%s; error='%s' (errno=%s)", msg, os::strerror(err), \
|
||||
os::errno_name(err)); \
|
||||
} while (false)
|
||||
|
||||
#define assert_with_errno(cond, msg) check_with_errno(assert, cond, msg)
|
||||
#define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
|
||||
|
||||
#ifndef NR_riscv_flush_icache
|
||||
#ifndef NR_arch_specific_syscall
|
||||
#define NR_arch_specific_syscall 244
|
||||
#endif
|
||||
#define NR_riscv_flush_icache (NR_arch_specific_syscall + 15)
|
||||
#endif
|
||||
|
||||
#define SYS_RISCV_FLUSH_ICACHE_LOCAL 1UL
|
||||
#define SYS_RISCV_FLUSH_ICACHE_ALL 0UL
|
||||
|
||||
static long sys_flush_icache(uintptr_t start, uintptr_t end , uintptr_t flags) {
|
||||
return syscall(NR_riscv_flush_icache, start, end, flags);
|
||||
}
|
||||
|
||||
bool RiscvFlushIcache::test() {
|
||||
alignas(64) char memory[64];
|
||||
long ret = sys_flush_icache((uintptr_t)&memory[0],
|
||||
(uintptr_t)&memory[sizeof(memory) - 1],
|
||||
SYS_RISCV_FLUSH_ICACHE_ALL);
|
||||
if (ret == 0) {
|
||||
return true;
|
||||
}
|
||||
int err = errno; \
|
||||
log_error(os)("Syscall: RISCV_FLUSH_ICACHE not available; error='%s' (errno=%s)",
|
||||
os::strerror(err), os::errno_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
void RiscvFlushIcache::flush(uintptr_t start, uintptr_t end) {
|
||||
long ret = sys_flush_icache(start, end, SYS_RISCV_FLUSH_ICACHE_ALL);
|
||||
guarantee_with_errno(ret == 0, "riscv_flush_icache failed");
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, Rivos Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
* 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
|
||||
@@ -21,19 +20,20 @@
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.font.lookup;
|
||||
#ifndef OS_LINUX_RISCV_FLUSH_ICACHE_LINUX_HPP
|
||||
#define OS_LINUX_RISCV_FLUSH_ICACHE_LINUX_HPP
|
||||
|
||||
import sun.font.SunFontManager;
|
||||
#include "memory/allStatic.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
||||
/**
|
||||
* Implementation-class accessed by other JDK modules to
|
||||
* locate the JDK-provided fonts.
|
||||
*/
|
||||
public final class JDKFontLookup {
|
||||
class RiscvFlushIcache: public AllStatic {
|
||||
public:
|
||||
static bool test();
|
||||
static void flush(uintptr_t start, uintptr_t end);
|
||||
};
|
||||
|
||||
public static final String getJDKFontDir() {
|
||||
return SunFontManager.getJDKFontDir();
|
||||
}
|
||||
}
|
||||
#endif // OS_LINUX_RISCV_FLUSH_ICACHE_LINUX_HPP
|
||||
152
src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp
Normal file
152
src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, Rivos Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "riscv_hwprobe.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
#include <sched.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Syscall defined in kernel 6.4 and the defines will be in asm/hwprobe.h
|
||||
#define RISCV_HWPROBE_KEY_MVENDORID 0
|
||||
#define RISCV_HWPROBE_KEY_MARCHID 1
|
||||
#define RISCV_HWPROBE_KEY_MIMPID 2
|
||||
|
||||
#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
|
||||
#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1 << 0)
|
||||
|
||||
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
|
||||
#define RISCV_HWPROBE_IMA_FD (1 << 0)
|
||||
#define RISCV_HWPROBE_IMA_C (1 << 1)
|
||||
#define RISCV_HWPROBE_IMA_V (1 << 2)
|
||||
#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
|
||||
#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
|
||||
#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
|
||||
|
||||
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
|
||||
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
|
||||
#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
|
||||
#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0)
|
||||
#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
|
||||
#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
|
||||
#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
|
||||
|
||||
#ifndef NR_riscv_hwprobe
|
||||
#ifndef NR_arch_specific_syscall
|
||||
#define NR_arch_specific_syscall 244
|
||||
#endif
|
||||
#define NR_riscv_hwprobe (NR_arch_specific_syscall + 14)
|
||||
#endif
|
||||
|
||||
struct riscv_hwprobe {
|
||||
int64_t key;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
long sys_riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pairc,
|
||||
size_t cpuc, cpu_set_t *cpus,
|
||||
unsigned int flags) {
|
||||
return syscall(NR_riscv_hwprobe, pairs, pairc, cpuc, cpus, 0 /* flags*/);
|
||||
}
|
||||
|
||||
static bool rw_hwprobe_completed = false;
|
||||
|
||||
static struct riscv_hwprobe query[] = {{RISCV_HWPROBE_KEY_MVENDORID, 0},
|
||||
{RISCV_HWPROBE_KEY_MARCHID, 0},
|
||||
{RISCV_HWPROBE_KEY_MIMPID, 0},
|
||||
{RISCV_HWPROBE_KEY_BASE_BEHAVIOR, 0},
|
||||
{RISCV_HWPROBE_KEY_IMA_EXT_0, 0},
|
||||
{RISCV_HWPROBE_KEY_CPUPERF_0, 0}};
|
||||
|
||||
bool RiscvHwprobe::probe_features() {
|
||||
assert(!rw_hwprobe_completed, "Called twice.");
|
||||
int ret = sys_riscv_hwprobe(&query[0], sizeof(query) / sizeof(query[0]), 0, nullptr, 0);
|
||||
rw_hwprobe_completed = true;
|
||||
if (ret != 0) {
|
||||
log_debug(os, cpu)("riscv_hwprobe unsupported");
|
||||
return false;
|
||||
}
|
||||
log_debug(os, cpu)("riscv_hwprobe supported");
|
||||
add_features_from_query_result();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_valid(int64_t key) {
|
||||
return query[key].key != -1;
|
||||
}
|
||||
|
||||
static bool is_set(int64_t key, uint64_t value_mask) {
|
||||
if (is_valid(key)) {
|
||||
return (query[key].value & value_mask) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RiscvHwprobe::add_features_from_query_result() {
|
||||
assert(rw_hwprobe_completed, "hwprobe not init yet.");
|
||||
|
||||
if (is_valid(RISCV_HWPROBE_KEY_MVENDORID)) {
|
||||
VM_Version::mvendorid.enable_feature(query[RISCV_HWPROBE_KEY_MVENDORID].value);
|
||||
}
|
||||
if (is_valid(RISCV_HWPROBE_KEY_MARCHID)) {
|
||||
VM_Version::marchid.enable_feature(query[RISCV_HWPROBE_KEY_MARCHID].value);
|
||||
}
|
||||
if (is_valid(RISCV_HWPROBE_KEY_MIMPID)) {
|
||||
VM_Version::mimpid.enable_feature(query[RISCV_HWPROBE_KEY_MIMPID].value);
|
||||
}
|
||||
if (is_set(RISCV_HWPROBE_KEY_BASE_BEHAVIOR, RISCV_HWPROBE_BASE_BEHAVIOR_IMA)) {
|
||||
VM_Version::ext_I.enable_feature();
|
||||
VM_Version::ext_M.enable_feature();
|
||||
VM_Version::ext_A.enable_feature();
|
||||
}
|
||||
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_IMA_FD)) {
|
||||
VM_Version::ext_F.enable_feature();
|
||||
VM_Version::ext_D.enable_feature();
|
||||
}
|
||||
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_IMA_C)) {
|
||||
VM_Version::ext_C.enable_feature();
|
||||
}
|
||||
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_IMA_V)) {
|
||||
VM_Version::ext_V.enable_feature();
|
||||
}
|
||||
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBA)) {
|
||||
VM_Version::ext_Zba.enable_feature();
|
||||
}
|
||||
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBB)) {
|
||||
VM_Version::ext_Zbb.enable_feature();
|
||||
}
|
||||
if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZBS)) {
|
||||
VM_Version::ext_Zbs.enable_feature();
|
||||
}
|
||||
if (is_valid(RISCV_HWPROBE_KEY_CPUPERF_0)) {
|
||||
VM_Version::unaligned_access.enable_feature(
|
||||
query[RISCV_HWPROBE_KEY_CPUPERF_0].value & RISCV_HWPROBE_MISALIGNED_MASK);
|
||||
}
|
||||
}
|
||||
39
src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.hpp
Normal file
39
src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, Rivos Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OS_LINUX_RISCV_HWPROBE_LINUX_HPP
|
||||
#define OS_LINUX_RISCV_HWPROBE_LINUX_HPP
|
||||
|
||||
#include "memory/allStatic.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
||||
class RiscvHwprobe: public AllStatic {
|
||||
static void add_features_from_query_result();
|
||||
public:
|
||||
static bool probe_features();
|
||||
};
|
||||
|
||||
#endif // OS_LINUX_RISCV_HWPROBE_LINUX_HPP
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2023, Rivos Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@@ -25,39 +26,50 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/register.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "riscv_hwprobe.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/os.inline.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
|
||||
#include <asm/hwcap.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/auxv.h>
|
||||
|
||||
#ifndef HWCAP_ISA_I
|
||||
#define HWCAP_ISA_I (1 << ('I' - 'A'))
|
||||
#define HWCAP_ISA_I nth_bit('I' - 'A')
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP_ISA_M
|
||||
#define HWCAP_ISA_M (1 << ('M' - 'A'))
|
||||
#define HWCAP_ISA_M nth_bit('M' - 'A')
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP_ISA_A
|
||||
#define HWCAP_ISA_A (1 << ('A' - 'A'))
|
||||
#define HWCAP_ISA_A nth_bit('A' - 'A')
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP_ISA_F
|
||||
#define HWCAP_ISA_F (1 << ('F' - 'A'))
|
||||
#define HWCAP_ISA_F nth_bit('F' - 'A')
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP_ISA_D
|
||||
#define HWCAP_ISA_D (1 << ('D' - 'A'))
|
||||
#define HWCAP_ISA_D nth_bit('D' - 'A')
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP_ISA_C
|
||||
#define HWCAP_ISA_C (1 << ('C' - 'A'))
|
||||
#define HWCAP_ISA_C nth_bit('C' - 'A')
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP_ISA_Q
|
||||
#define HWCAP_ISA_Q nth_bit('Q' - 'A')
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP_ISA_H
|
||||
#define HWCAP_ISA_H nth_bit('H' - 'A')
|
||||
#endif
|
||||
|
||||
#ifndef HWCAP_ISA_V
|
||||
#define HWCAP_ISA_V (1 << ('V' - 'A'))
|
||||
#define HWCAP_ISA_V nth_bit('V' - 'A')
|
||||
#endif
|
||||
|
||||
#define read_csr(csr) \
|
||||
@@ -70,68 +82,174 @@
|
||||
__v; \
|
||||
})
|
||||
|
||||
uint32_t VM_Version::get_current_vector_length() {
|
||||
assert(_features & CPU_V, "should not call this");
|
||||
uint32_t VM_Version::cpu_vector_length() {
|
||||
assert(ext_V.enabled(), "should not call this");
|
||||
return (uint32_t)read_csr(CSR_VLENB);
|
||||
}
|
||||
|
||||
VM_Version::VM_MODE VM_Version::get_satp_mode() {
|
||||
if (!strcmp(_vm_mode, "sv39")) {
|
||||
void VM_Version::setup_cpu_available_features() {
|
||||
|
||||
assert(ext_I.feature_bit() == HWCAP_ISA_I, "Bit for I must follow Linux HWCAP");
|
||||
assert(ext_M.feature_bit() == HWCAP_ISA_M, "Bit for M must follow Linux HWCAP");
|
||||
assert(ext_A.feature_bit() == HWCAP_ISA_A, "Bit for A must follow Linux HWCAP");
|
||||
assert(ext_F.feature_bit() == HWCAP_ISA_F, "Bit for F must follow Linux HWCAP");
|
||||
assert(ext_D.feature_bit() == HWCAP_ISA_D, "Bit for D must follow Linux HWCAP");
|
||||
assert(ext_C.feature_bit() == HWCAP_ISA_C, "Bit for C must follow Linux HWCAP");
|
||||
assert(ext_Q.feature_bit() == HWCAP_ISA_Q, "Bit for Q must follow Linux HWCAP");
|
||||
assert(ext_H.feature_bit() == HWCAP_ISA_H, "Bit for H must follow Linux HWCAP");
|
||||
assert(ext_V.feature_bit() == HWCAP_ISA_V, "Bit for V must follow Linux HWCAP");
|
||||
|
||||
if (!RiscvHwprobe::probe_features()) {
|
||||
os_aux_features();
|
||||
}
|
||||
char* uarch = os_uarch_additional_features();
|
||||
vendor_features();
|
||||
|
||||
char buf[1024] = {};
|
||||
if (uarch != nullptr && strcmp(uarch, "") != 0) {
|
||||
// Use at max half the buffer.
|
||||
snprintf(buf, sizeof(buf)/2, "%s,", uarch);
|
||||
}
|
||||
os::free((void*) uarch);
|
||||
strcat(buf, "rv64");
|
||||
int i = 0;
|
||||
while (_feature_list[i] != nullptr) {
|
||||
if (_feature_list[i]->enabled()) {
|
||||
log_debug(os, cpu)("Enabled RV64 feature \"%s\" (%ld)",
|
||||
_feature_list[i]->pretty(),
|
||||
_feature_list[i]->value());
|
||||
// The feature string
|
||||
if (_feature_list[i]->feature_string()) {
|
||||
const char* tmp = _feature_list[i]->pretty();
|
||||
if (strlen(tmp) == 1) {
|
||||
strcat(buf, tmp);
|
||||
} else {
|
||||
// Feature string is expected to be lower case.
|
||||
// Turn Zxxx into zxxx
|
||||
char prebuf[3] = {};
|
||||
assert(strlen(tmp) > 1, "Must be");
|
||||
prebuf[0] = '_';
|
||||
prebuf[1] = (char)tolower(tmp[0]);
|
||||
strcat(buf, prebuf);
|
||||
strcat(buf, &tmp[1]);
|
||||
}
|
||||
}
|
||||
// Feature bit
|
||||
if (_feature_list[i]->feature_bit() != 0) {
|
||||
_features |= _feature_list[i]->feature_bit();
|
||||
}
|
||||
// Change flag default
|
||||
_feature_list[i]->update_flag();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
_features_string = os::strdup(buf);
|
||||
}
|
||||
|
||||
void VM_Version::os_aux_features() {
|
||||
uint64_t auxv = getauxval(AT_HWCAP);
|
||||
for (int i = 0; _feature_list[i] != nullptr; i++) {
|
||||
if (_feature_list[i]->feature_bit() == HWCAP_ISA_V) {
|
||||
// Special case for V: some dev boards only support RVV version 0.7, while
|
||||
// the OpenJDK only supports RVV version 1.0. These two versions are not
|
||||
// compatible with each other. Given the V bit is set through HWCAP on
|
||||
// some custom kernels, regardless of the version, it can lead to
|
||||
// generating V instructions on boards that don't support RVV version 1.0
|
||||
// (ex: Sipeed LicheePi), leading to a SIGILL.
|
||||
// That is an acceptable workaround as only Linux Kernel v6.5+ supports V,
|
||||
// and that version already support hwprobe anyway
|
||||
continue;
|
||||
}
|
||||
if ((_feature_list[i]->feature_bit() & auxv) != 0) {
|
||||
_feature_list[i]->enable_feature();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VM_Version::VM_MODE VM_Version::parse_satp_mode(const char* vm_mode) {
|
||||
if (!strcmp(vm_mode, "sv39")) {
|
||||
return VM_SV39;
|
||||
} else if (!strcmp(_vm_mode, "sv48")) {
|
||||
} else if (!strcmp(vm_mode, "sv48")) {
|
||||
return VM_SV48;
|
||||
} else if (!strcmp(_vm_mode, "sv57")) {
|
||||
} else if (!strcmp(vm_mode, "sv57")) {
|
||||
return VM_SV57;
|
||||
} else if (!strcmp(_vm_mode, "sv64")) {
|
||||
} else if (!strcmp(vm_mode, "sv64")) {
|
||||
return VM_SV64;
|
||||
} else {
|
||||
return VM_MBARE;
|
||||
}
|
||||
}
|
||||
|
||||
void VM_Version::get_os_cpu_info() {
|
||||
char* VM_Version::os_uarch_additional_features() {
|
||||
char* ret = nullptr;
|
||||
VM_MODE mode = VM_NOTSET;
|
||||
|
||||
uint64_t auxv = getauxval(AT_HWCAP);
|
||||
FILE *f = fopen("/proc/cpuinfo", "r");
|
||||
if (f == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static_assert(CPU_I == HWCAP_ISA_I, "Flag CPU_I must follow Linux HWCAP");
|
||||
static_assert(CPU_M == HWCAP_ISA_M, "Flag CPU_M must follow Linux HWCAP");
|
||||
static_assert(CPU_A == HWCAP_ISA_A, "Flag CPU_A must follow Linux HWCAP");
|
||||
static_assert(CPU_F == HWCAP_ISA_F, "Flag CPU_F must follow Linux HWCAP");
|
||||
static_assert(CPU_D == HWCAP_ISA_D, "Flag CPU_D must follow Linux HWCAP");
|
||||
static_assert(CPU_C == HWCAP_ISA_C, "Flag CPU_C must follow Linux HWCAP");
|
||||
static_assert(CPU_V == HWCAP_ISA_V, "Flag CPU_V must follow Linux HWCAP");
|
||||
|
||||
// RISC-V has four bit-manipulation ISA-extensions: Zba/Zbb/Zbc/Zbs.
|
||||
// Availability for those extensions could not be queried from HWCAP.
|
||||
// TODO: Add proper detection for those extensions.
|
||||
_features = auxv & (
|
||||
HWCAP_ISA_I |
|
||||
HWCAP_ISA_M |
|
||||
HWCAP_ISA_A |
|
||||
HWCAP_ISA_F |
|
||||
HWCAP_ISA_D |
|
||||
HWCAP_ISA_C |
|
||||
HWCAP_ISA_V);
|
||||
|
||||
if (FILE *f = fopen("/proc/cpuinfo", "r")) {
|
||||
char buf[512], *p;
|
||||
while (fgets(buf, sizeof (buf), f) != NULL) {
|
||||
if ((p = strchr(buf, ':')) != NULL) {
|
||||
char buf[512], *p;
|
||||
while (fgets(buf, sizeof (buf), f) != nullptr &&
|
||||
(mode == VM_NOTSET || ret == nullptr)) {
|
||||
if ((p = strchr(buf, ':')) != nullptr) {
|
||||
if (mode == VM_NOTSET) {
|
||||
if (strncmp(buf, "mmu", sizeof "mmu" - 1) == 0) {
|
||||
if (_vm_mode[0] != '\0') {
|
||||
continue;
|
||||
}
|
||||
char* vm_mode = os::strdup(p + 2);
|
||||
vm_mode[strcspn(vm_mode, "\n")] = '\0';
|
||||
_vm_mode = vm_mode;
|
||||
} else if (strncmp(buf, "uarch", sizeof "uarch" - 1) == 0) {
|
||||
char* uarch = os::strdup(p + 2);
|
||||
uarch[strcspn(uarch, "\n")] = '\0';
|
||||
_uarch = uarch;
|
||||
break;
|
||||
mode = VM_Version::parse_satp_mode(p);
|
||||
}
|
||||
}
|
||||
if (ret == nullptr) {
|
||||
if (strncmp(buf, "uarch", sizeof "uarch" - 1) == 0) {
|
||||
ret = os::strdup(p + 2);
|
||||
ret[strcspn(ret, "\n")] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
if (mode == VM_NOTSET) {
|
||||
mode = VM_MBARE;
|
||||
}
|
||||
fclose(f);
|
||||
satp_mode.enable_feature(mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VM_Version::vendor_features() {
|
||||
// JEDEC encoded as ((bank - 1) << 7) | (0x7f & JEDEC)
|
||||
static constexpr int RIVOS_MVENDORID = 0x6cf; // JEDEC: 0x4f, Bank: 14
|
||||
|
||||
if (!mvendorid.enabled()) {
|
||||
return;
|
||||
}
|
||||
switch (mvendorid.value()) {
|
||||
case RIVOS_MVENDORID:
|
||||
rivos_features();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VM_Version::rivos_features() {
|
||||
// Enable common features not dependent on marchid/mimpid.
|
||||
ext_Zicbom.enable_feature();
|
||||
ext_Zicboz.enable_feature();
|
||||
ext_Zicbop.enable_feature();
|
||||
|
||||
// If we running on a pre-6.5 kernel
|
||||
ext_Zba.enable_feature();
|
||||
ext_Zbb.enable_feature();
|
||||
ext_Zbs.enable_feature();
|
||||
|
||||
ext_Zicsr.enable_feature();
|
||||
ext_Zifencei.enable_feature();
|
||||
ext_Zic64b.enable_feature();
|
||||
ext_Zihintpause.enable_feature();
|
||||
|
||||
unaligned_access.enable_feature(MISALIGNED_FAST);
|
||||
satp_mode.enable_feature(VM_SV48);
|
||||
|
||||
// Features dependent on march/mimpid.
|
||||
// I.e. march.value() and mimplid.value()
|
||||
}
|
||||
|
||||
@@ -2009,9 +2009,10 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
|
||||
assert(singleton != declared_interface, "not a unique implementor");
|
||||
cha_monomorphic_target = target->find_monomorphic_target(calling_klass, declared_interface, singleton);
|
||||
if (cha_monomorphic_target != NULL) {
|
||||
if (cha_monomorphic_target->holder() != compilation()->env()->Object_klass()) {
|
||||
ciInstanceKlass* holder = cha_monomorphic_target->holder();
|
||||
ciInstanceKlass* constraint = (holder->is_subtype_of(singleton) ? holder : singleton); // avoid upcasts
|
||||
ciInstanceKlass* holder = cha_monomorphic_target->holder();
|
||||
ciInstanceKlass* constraint = (holder->is_subtype_of(singleton) ? holder : singleton); // avoid upcasts
|
||||
if (holder != compilation()->env()->Object_klass() &&
|
||||
(!type_is_exact || receiver_klass->is_subtype_of(constraint))) {
|
||||
actual_recv = declared_interface;
|
||||
|
||||
// insert a check it's really the expected class.
|
||||
@@ -2024,7 +2025,7 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
|
||||
|
||||
dependency_recorder()->assert_unique_implementor(declared_interface, singleton);
|
||||
} else {
|
||||
cha_monomorphic_target = NULL; // subtype check against Object is useless
|
||||
cha_monomorphic_target = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ void PhiResolverState::reset() {
|
||||
PhiResolver::PhiResolver(LIRGenerator* gen)
|
||||
: _gen(gen)
|
||||
, _state(gen->resolver_state())
|
||||
, _loop(nullptr)
|
||||
, _temp(LIR_OprFact::illegalOpr)
|
||||
{
|
||||
// reinitialize the shared state arrays
|
||||
|
||||
@@ -404,8 +404,11 @@ void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int
|
||||
aii->_max = idx;
|
||||
aii->_list = new AccessIndexedList();
|
||||
} else if (idx >= aii->_min && idx <= aii->_max) {
|
||||
remove_range_check(ai);
|
||||
return;
|
||||
// Guard against underflow/overflow (see 'range_cond' check in RangeCheckEliminator::in_block_motion)
|
||||
if (aii->_max < 0 || (aii->_max + min_jint) <= aii->_min) {
|
||||
remove_range_check(ai);
|
||||
return;
|
||||
}
|
||||
}
|
||||
aii->_min = MIN2(aii->_min, idx);
|
||||
aii->_max = MAX2(aii->_max, idx);
|
||||
@@ -448,9 +451,9 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int last_integer = 0;
|
||||
jint last_integer = 0;
|
||||
Instruction *last_instruction = index;
|
||||
int base = 0;
|
||||
jint base = 0;
|
||||
ArithmeticOp *ao = index->as_ArithmeticOp();
|
||||
|
||||
while (ao != NULL && (ao->x()->as_Constant() || ao->y()->as_Constant()) && (ao->op() == Bytecodes::_iadd || ao->op() == Bytecodes::_isub)) {
|
||||
@@ -462,12 +465,12 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
|
||||
}
|
||||
|
||||
if (c) {
|
||||
int value = c->type()->as_IntConstant()->value();
|
||||
jint value = c->type()->as_IntConstant()->value();
|
||||
if (value != min_jint) {
|
||||
if (ao->op() == Bytecodes::_isub) {
|
||||
value = -value;
|
||||
}
|
||||
base += value;
|
||||
base = java_add(base, value);
|
||||
last_integer = base;
|
||||
last_instruction = other;
|
||||
}
|
||||
@@ -489,12 +492,12 @@ void RangeCheckEliminator::in_block_motion(BlockBegin *block, AccessIndexedList
|
||||
assert(info != NULL, "Info must not be null");
|
||||
|
||||
// if idx < 0, max > 0, max + idx may fall between 0 and
|
||||
// length-1 and if min < 0, min + idx may overflow and be >=
|
||||
// length-1 and if min < 0, min + idx may underflow/overflow and be >=
|
||||
// 0. The predicate wouldn't trigger but some accesses could
|
||||
// be with a negative index. This test guarantees that for the
|
||||
// min and max value that are kept the predicate can't let
|
||||
// some incorrect accesses happen.
|
||||
bool range_cond = (info->_max < 0 || info->_max + min_jint <= info->_min);
|
||||
bool range_cond = (info->_max < 0 || (info->_max + min_jint) <= info->_min);
|
||||
|
||||
// Generate code only if more than 2 range checks can be eliminated because of that.
|
||||
// 2 because at least 2 comparisons are done
|
||||
@@ -843,7 +846,7 @@ void RangeCheckEliminator::process_access_indexed(BlockBegin *loop_header, Block
|
||||
);
|
||||
|
||||
remove_range_check(ai);
|
||||
} else if (_optimistic && loop_header) {
|
||||
} else if (false && _optimistic && loop_header) {
|
||||
assert(ai->array(), "Array must not be null!");
|
||||
assert(ai->index(), "Index must not be null!");
|
||||
|
||||
|
||||
@@ -359,6 +359,33 @@ LoopInvariantCodeMotion::LoopInvariantCodeMotion(ShortLoopOptimizer *slo, Global
|
||||
}
|
||||
}
|
||||
|
||||
class CheckInsertionPoint : public ValueVisitor {
|
||||
private:
|
||||
Value _insert;
|
||||
bool _valid = true;
|
||||
|
||||
void visit(Value* vp) {
|
||||
assert(*vp != nullptr, "value should not be null");
|
||||
if (_insert->dominator_depth() < (*vp)->dominator_depth()) {
|
||||
_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool is_valid() { return _valid; }
|
||||
CheckInsertionPoint(Value insert)
|
||||
: _insert(insert) {
|
||||
assert(insert != nullptr, "insertion point should not be null");
|
||||
}
|
||||
};
|
||||
|
||||
// Check that insertion point has higher dom depth than all inputs to cur
|
||||
static bool is_dominated_by_inputs(Instruction* insertion_point, Instruction* cur) {
|
||||
CheckInsertionPoint v(insertion_point);
|
||||
cur->input_values_do(&v);
|
||||
return v.is_valid();
|
||||
}
|
||||
|
||||
void LoopInvariantCodeMotion::process_block(BlockBegin* block) {
|
||||
TRACE_VALUE_NUMBERING(tty->print_cr("processing block B%d", block->block_id()));
|
||||
|
||||
@@ -394,7 +421,7 @@ void LoopInvariantCodeMotion::process_block(BlockBegin* block) {
|
||||
cur_invariant = is_invariant(cvt->value());
|
||||
}
|
||||
|
||||
if (cur_invariant) {
|
||||
if (cur_invariant && is_dominated_by_inputs(_insertion_point, cur)) {
|
||||
// perform value numbering and mark instruction as loop-invariant
|
||||
_gvn->substitute(cur);
|
||||
|
||||
|
||||
@@ -407,16 +407,17 @@ bool SharedClassPathEntry::validate(bool is_class_path) const {
|
||||
FileMapInfo::fail_continue("directory is not empty: %s", name);
|
||||
ok = false;
|
||||
}
|
||||
} else if ((has_timestamp() && _timestamp != st.st_mtime) ||
|
||||
_filesize != st.st_size) {
|
||||
ok = false;
|
||||
if (PrintSharedArchiveAndExit) {
|
||||
FileMapInfo::fail_continue(_timestamp != st.st_mtime ?
|
||||
"Timestamp mismatch" :
|
||||
"File size mismatch");
|
||||
} else {
|
||||
FileMapInfo::fail_continue("A jar file is not the one used while building"
|
||||
" the shared archive file: %s", name);
|
||||
} else {
|
||||
bool size_differs = _filesize != st.st_size;
|
||||
bool time_differs = has_timestamp() && _timestamp != st.st_mtime;
|
||||
if (time_differs || size_differs) {
|
||||
ok = false;
|
||||
if (PrintSharedArchiveAndExit) {
|
||||
FileMapInfo::fail_continue(time_differs ? "Timestamp mismatch" : "File size mismatch");
|
||||
} else {
|
||||
FileMapInfo::fail_continue("This file is not the one used while building"
|
||||
" the shared archive file: %s", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -658,7 +658,7 @@ void HeapShared::serialize_subgraph_info_table_header(SerializeClosure* soc) {
|
||||
}
|
||||
|
||||
static void verify_the_heap(Klass* k, const char* which) {
|
||||
if (VerifyArchivedFields) {
|
||||
if (VerifyArchivedFields > 0) {
|
||||
ResourceMark rm;
|
||||
log_info(cds, heap)("Verify heap %s initializing static field(s) in %s",
|
||||
which, k->external_name());
|
||||
@@ -666,15 +666,20 @@ static void verify_the_heap(Klass* k, const char* which) {
|
||||
VM_Verify verify_op;
|
||||
VMThread::execute(&verify_op);
|
||||
|
||||
if (!FLAG_IS_DEFAULT(VerifyArchivedFields)) {
|
||||
// If VerifyArchivedFields has a non-default value (e.g., specified on the command-line), do
|
||||
// more expensive checks.
|
||||
if (is_init_completed()) {
|
||||
FlagSetting fs1(VerifyBeforeGC, true);
|
||||
FlagSetting fs2(VerifyDuringGC, true);
|
||||
FlagSetting fs3(VerifyAfterGC, true);
|
||||
Universe::heap()->collect(GCCause::_java_lang_system_gc);
|
||||
}
|
||||
if (VerifyArchivedFields > 1 && is_init_completed()) {
|
||||
// At this time, the oop->klass() of some archived objects in the heap may not
|
||||
// have been loaded into the system dictionary yet. Nevertheless, oop->klass() should
|
||||
// have enough information (object size, oop maps, etc) so that a GC can be safely
|
||||
// performed.
|
||||
//
|
||||
// -XX:VerifyArchivedFields=2 force a GC to happen in such an early stage
|
||||
// to check for GC safety.
|
||||
log_info(cds, heap)("Trigger GC %s initializing static field(s) in %s",
|
||||
which, k->external_name());
|
||||
FlagSetting fs1(VerifyBeforeGC, true);
|
||||
FlagSetting fs2(VerifyDuringGC, true);
|
||||
FlagSetting fs3(VerifyAfterGC, true);
|
||||
Universe::heap()->collect(GCCause::_java_lang_system_gc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
//
|
||||
// Set the unique identity number of a ciBaseObject.
|
||||
void ciBaseObject::set_ident(uint id) {
|
||||
assert(_ident == 0, "must only initialize once");
|
||||
assert(AllowEnhancedClassRedefinition || _ident == 0, "must only initialize once");
|
||||
_ident = id;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ ciEnv::ciEnv(Arena* arena) : _ciEnv_arena(mtCompiler) {
|
||||
_break_at_compile = false;
|
||||
_compiler_data = NULL;
|
||||
#ifndef PRODUCT
|
||||
assert(firstEnv, "must be first");
|
||||
assert(AllowEnhancedClassRedefinition || firstEnv, "must be first");
|
||||
firstEnv = false;
|
||||
#endif /* !PRODUCT */
|
||||
|
||||
@@ -1250,6 +1250,7 @@ void ciEnv::dump_replay_data(int compile_id) {
|
||||
tty->print_cr("# Compiler replay data is saved as: %s", buffer);
|
||||
} else {
|
||||
tty->print_cr("# Can't open file to dump replay data.");
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1273,6 +1274,7 @@ void ciEnv::dump_inline_data(int compile_id) {
|
||||
tty->print_cr("%s", buffer);
|
||||
} else {
|
||||
tty->print_cr("# Can't open file to dump inline data.");
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,37 +119,16 @@ void ciObjectFactory::initialize() {
|
||||
env->_factory->init_shared_objects();
|
||||
|
||||
_initialized = true;
|
||||
|
||||
}
|
||||
|
||||
// (DCEVM) vm classes could be modified
|
||||
void ciObjectFactory::reinitialize_vm_classes() {
|
||||
ASSERT_IN_VM;
|
||||
JavaThread* thread = JavaThread::current();
|
||||
HandleMark handle_mark(thread);
|
||||
|
||||
// This Arena is long lived and exists in the resource mark of the
|
||||
// compiler thread that initializes the initial ciObjectFactory which
|
||||
// creates the shared ciObjects that all later ciObjectFactories use.
|
||||
// Arena* arena = new (mtCompiler) Arena(mtCompiler);
|
||||
ciEnv initial(ciObjectFactory::_initial_arena);
|
||||
ciEnv* env = ciEnv::current();
|
||||
env->_factory->do_reinitialize_vm_classes();
|
||||
void ciObjectFactory::reinitialize_vm_classes_dcevm() {
|
||||
// TODO: compiler crashes after 'delete _initial_arena;'
|
||||
// delete ciObjectFactory::_initial_arena;
|
||||
_initialized = false;
|
||||
ciObjectFactory::initialize();
|
||||
_reinitialize_vm_klasses = false;
|
||||
}
|
||||
|
||||
// (DCEVM) vm classes could be modified
|
||||
void ciObjectFactory::do_reinitialize_vm_classes() {
|
||||
#define VM_CLASS_DEFN(name, ignore_s) \
|
||||
if (ciEnv::_##name != NULL && ciEnv::_##name->new_version() != NULL) { \
|
||||
int old_ident = ciEnv::_##name->ident(); \
|
||||
ciEnv::_##name = get_metadata(vmClasses::name())->as_instance_klass(); \
|
||||
ciEnv::_##name->compute_nonstatic_fields(); \
|
||||
ciEnv::_##name->set_ident(old_ident); \
|
||||
}
|
||||
|
||||
VM_CLASSES_DO(VM_CLASS_DEFN)
|
||||
#undef VM_CLASS_DEFN
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void ciObjectFactory::init_shared_objects() {
|
||||
@@ -751,14 +730,13 @@ void ciObjectFactory::print() {
|
||||
_unloaded_klasses.length());
|
||||
}
|
||||
|
||||
|
||||
int ciObjectFactory::compare_cimetadata(ciMetadata** a, ciMetadata** b) {
|
||||
Metadata* am = (*a)->constant_encoding();
|
||||
Metadata* bm = (*b)->constant_encoding();
|
||||
return ((am > bm) ? 1 : ((am == bm) ? 0 : -1));
|
||||
}
|
||||
|
||||
// FIXME: review... Resoring the ciObject arrays after class redefinition
|
||||
// FIXME: review... is it necessary?
|
||||
void ciObjectFactory::resort_shared_ci_metadata() {
|
||||
if (_shared_ci_metadata == NULL) return;
|
||||
_shared_ci_metadata->sort(ciObjectFactory::compare_cimetadata);
|
||||
@@ -774,4 +752,3 @@ void ciObjectFactory::resort_shared_ci_metadata() {
|
||||
}
|
||||
#endif // ASSERT
|
||||
}
|
||||
|
||||
|
||||
@@ -92,14 +92,15 @@ private:
|
||||
ciInstance* get_unloaded_instance(ciInstanceKlass* klass);
|
||||
|
||||
static int compare_cimetadata(ciMetadata** a, ciMetadata** b);
|
||||
void do_reinitialize_vm_classes();
|
||||
public:
|
||||
static bool is_initialized() { return _initialized; }
|
||||
|
||||
// (DCEVM)
|
||||
static bool is_reinitialize_vm_klasses() { return _reinitialize_vm_klasses; }
|
||||
static void set_reinitialize_vm_klasses() { _reinitialize_vm_klasses = true; }
|
||||
static void reinitialize_vm_classes_dcevm();
|
||||
|
||||
static void initialize();
|
||||
static void reinitialize_vm_classes();
|
||||
void init_shared_objects();
|
||||
void remove_symbols();
|
||||
|
||||
|
||||
@@ -326,7 +326,10 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
return (unsigned)((uintptr_t)this >> 3);
|
||||
}
|
||||
|
||||
JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
|
||||
int keep_alive_cnt() const { return _keep_alive; }
|
||||
|
||||
|
||||
JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
|
||||
};
|
||||
|
||||
#endif // SHARE_CLASSFILE_CLASSLOADERDATA_HPP
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user