|
5 | 5 |
|
6 | 6 | import org.jetbrains.annotations.NotNull; |
7 | 7 |
|
8 | | -import java.lang.invoke.MethodHandle; |
9 | | -import java.lang.invoke.MethodHandles; |
10 | | -import java.lang.reflect.Method; |
11 | | - |
| 8 | +@SuppressWarnings("Since15") |
12 | 9 | class Maths { |
13 | 10 | @NotNull |
14 | 11 | private static final Maths INSTANCE; |
15 | 12 |
|
16 | 13 | static { |
17 | | - Maths maths = null; |
| 14 | + boolean hasMultiplyHigh = true; |
18 | 15 | try { |
19 | | - Method multiplyHigh = Math.class.getDeclaredMethod("multiplyHigh", int.class, int.class); |
20 | | - MethodHandle multiplyHighMH = MethodHandles.lookup().unreflect(multiplyHigh); |
21 | | - maths = new MathsJDK9(multiplyHighMH); |
| 16 | + // stubs in src/main/java-stub are used to allow this to compile in Java 8+ |
| 17 | + Math.multiplyHigh(0, 0); |
22 | 18 | } catch (final Throwable ignore) { |
23 | | - maths = new Maths(); |
| 19 | + hasMultiplyHigh = false; |
24 | 20 | } |
25 | | - INSTANCE = maths; |
| 21 | + INSTANCE = hasMultiplyHigh ? new MathsJDK9() : new Maths(); |
26 | 22 | } |
27 | 23 |
|
28 | 24 | public static long unsignedLongMulXorFold(final long lhs, final long rhs) { |
29 | 25 | return INSTANCE.unsignedLongMulXorFoldImp(lhs, rhs); |
30 | 26 | } |
| 27 | + |
31 | 28 | public static long unsignedLongMulHigh(final long lhs, final long rhs) { |
32 | 29 | return INSTANCE.unsignedLongMulHighImp(lhs, rhs); |
33 | 30 | } |
@@ -70,31 +67,19 @@ long unsignedLongMulHighImp(final long lhs, final long rhs) { |
70 | 67 | } |
71 | 68 | } |
72 | 69 |
|
| 70 | +@SuppressWarnings("Since15") |
73 | 71 | class MathsJDK9 extends Maths { |
74 | | - private final MethodHandle multiplyHighMH; |
75 | | - |
76 | | - public MathsJDK9(MethodHandle multiplyHighMH) { |
77 | | - this.multiplyHighMH = multiplyHighMH; |
78 | | - } |
79 | | - |
80 | 72 | // Math.multiplyHigh() is intrinsified from JDK 10. But JDK 9 is out of life, we always prefer |
81 | 73 | // this version to the scalar one. |
82 | 74 | @Override |
83 | 75 | long unsignedLongMulXorFoldImp(final long lhs, final long rhs) { |
84 | | - final long upper = invokeExact(lhs, rhs) + ((lhs >> 63) & rhs) + ((rhs >> 63) & lhs); |
| 76 | + final long upper = Math.multiplyHigh(lhs, rhs) + ((lhs >> 63) & rhs) + ((rhs >> 63) & lhs); |
85 | 77 | final long lower = lhs * rhs; |
86 | 78 | return lower ^ upper; |
87 | 79 | } |
| 80 | + |
88 | 81 | @Override |
89 | 82 | long unsignedLongMulHighImp(final long lhs, final long rhs) { |
90 | | - return invokeExact(lhs, rhs) + ((lhs >> 63) & rhs) + ((rhs >> 63) & lhs); |
91 | | - } |
92 | | - |
93 | | - private long invokeExact(long lhs, long rhs) { |
94 | | - try { |
95 | | - return (long) multiplyHighMH.invokeExact(lhs, rhs); |
96 | | - } catch (Throwable e) { |
97 | | - throw new AssertionError(e); |
98 | | - } |
| 83 | + return Math.multiplyHigh(lhs, rhs) + ((lhs >> 63) & rhs) + ((rhs >> 63) & lhs); |
99 | 84 | } |
100 | 85 | } |
0 commit comments