-
Enhancement
-
Resolution: Fixed
-
P4
-
17, 19, 20
-
b27
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8306971 | 17.0.9-oracle | Tobias Hartmann | P4 | Resolved | Fixed | b01 |
JDK-8306873 | 17.0.8 | Aleksey Shipilev | P4 | Resolved | Fixed | b01 |
If you look at generated code for the JMH benchmark like:
```
@Param({"1", "100", "10000", "1000000"})
int size;
int[] is;
@Setup
public void setup() {
is = new int[size];
for (int c = 0; c < size; c++) {
is[c] = c;
}
}
@Benchmark
public void test(Blackhole bh) {
for (int i = 0; i < is.length; i++) {
bh.consume(is[i]);
}
}
```
...then you would notice that the loop always re-reads `is`, `is.length`, does the range check, etc. -- all the things we would otherwise expect to be hoisted out of the loop.
This is because C2 blackholes are modeled as membars that pinch both control and memory slices (like you would expect from the opaque non-inlined call), therefore every iteration has to re-read the referenced memory contents and recompute everything dependent on those loads. This behavior is not new -- the old, non-compiler blackholes were doing the same thing, accidentally -- but it was drowned in blackhole overheads. Now, these effects are clearly visible.
We can try to do this a bit better: allow load optimizations to work across the blackholes, leaving only "prevent dead code elimination" part, as minimally required by blackhole semantics.
```
@Param({"1", "100", "10000", "1000000"})
int size;
int[] is;
@Setup
public void setup() {
is = new int[size];
for (int c = 0; c < size; c++) {
is[c] = c;
}
}
@Benchmark
public void test(Blackhole bh) {
for (int i = 0; i < is.length; i++) {
bh.consume(is[i]);
}
}
```
...then you would notice that the loop always re-reads `is`, `is.length`, does the range check, etc. -- all the things we would otherwise expect to be hoisted out of the loop.
This is because C2 blackholes are modeled as membars that pinch both control and memory slices (like you would expect from the opaque non-inlined call), therefore every iteration has to re-read the referenced memory contents and recompute everything dependent on those loads. This behavior is not new -- the old, non-compiler blackholes were doing the same thing, accidentally -- but it was drowned in blackhole overheads. Now, these effects are clearly visible.
We can try to do this a bit better: allow load optimizations to work across the blackholes, leaving only "prevent dead code elimination" part, as minimally required by blackhole semantics.
- backported by
-
JDK-8306873 C2 Blackholes should allow load optimizations
- Resolved
-
JDK-8306971 C2 Blackholes should allow load optimizations
- Resolved
- relates to
-
JDK-8259316 [REDO] C1/C2 compiler support for blackholes
- Resolved
- links to
-
Commit openjdk/jdk17u-dev/e1326051
-
Commit openjdk/jdk/eab0ada3
-
Review openjdk/jdk17u-dev/1273
-
Review openjdk/jdk/11041
(2 links to)