8155795: Optimize Integer/Long.reverse by using reverseBytes
Reviewed-by: redestad, shade
Contributed-by: jaroslav@kamenik.cz
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java Tue May 10 15:12:04 2016 +0800
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java Tue May 10 13:28:00 2016 +0200
@@ -1790,9 +1790,8 @@
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
- i = (i << 24) | ((i & 0xff00) << 8) |
- ((i >>> 8) & 0xff00) | (i >>> 24);
- return i;
+
+ return reverseBytes(i);
}
/**
@@ -1820,10 +1819,10 @@
*/
@HotSpotIntrinsicCandidate
public static int reverseBytes(int i) {
- return ((i >>> 24) ) |
- ((i >> 8) & 0xFF00) |
- ((i << 8) & 0xFF0000) |
- ((i << 24));
+ return (i << 24) |
+ ((i & 0xff00) << 8) |
+ ((i >>> 8) & 0xff00) |
+ (i >>> 24);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/Long.java Tue May 10 15:12:04 2016 +0800
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java Tue May 10 13:28:00 2016 +0200
@@ -1952,10 +1952,8 @@
i = (i & 0x5555555555555555L) << 1 | (i >>> 1) & 0x5555555555555555L;
i = (i & 0x3333333333333333L) << 2 | (i >>> 2) & 0x3333333333333333L;
i = (i & 0x0f0f0f0f0f0f0f0fL) << 4 | (i >>> 4) & 0x0f0f0f0f0f0f0f0fL;
- i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
- i = (i << 48) | ((i & 0xffff0000L) << 16) |
- ((i >>> 16) & 0xffff0000L) | (i >>> 48);
- return i;
+
+ return reverseBytes(i);
}
/**
--- a/jdk/test/java/lang/Integer/BitTwiddle.java Tue May 10 15:12:04 2016 +0800
+++ b/jdk/test/java/lang/Integer/BitTwiddle.java Tue May 10 13:28:00 2016 +0200
@@ -58,6 +58,21 @@
for (int i = 0; i < N; i++) {
int x = rnd.nextInt();
+
+ String expected = new StringBuilder()
+ .append(leftpad(toBinaryString(x), 32))
+ .reverse().toString();
+
+ String actual = leftpad(toBinaryString(reverse(x)), 32);
+
+ if (!expected.equals(actual)) {
+ throw new RuntimeException("reverse: \n" +
+ expected + " \n" + actual);
+ }
+ }
+
+ for (int i = 0; i < N; i++) {
+ int x = rnd.nextInt();
if (highestOneBit(x) != reverse(lowestOneBit(reverse(x))))
throw new RuntimeException("g: " + toHexString(x));
}
@@ -136,4 +151,12 @@
throw new RuntimeException("z: " + toHexString(x));
}
}
+
+ private static String leftpad(String s, int width) {
+ String r = s;
+ for (int c = 0; c < width - s.length(); c++) {
+ r = "0" + r;
+ }
+ return r;
+ }
}
--- a/jdk/test/java/lang/Long/BitTwiddle.java Tue May 10 15:12:04 2016 +0800
+++ b/jdk/test/java/lang/Long/BitTwiddle.java Tue May 10 13:28:00 2016 +0200
@@ -58,6 +58,21 @@
for (int i = 0; i < N; i++) {
long x = rnd.nextLong();
+
+ String expected = new StringBuilder()
+ .append(leftpad(toBinaryString(x), 64))
+ .reverse().toString();
+
+ String actual = leftpad(toBinaryString(reverse(x)), 64);
+
+ if (!expected.equals(actual)) {
+ throw new RuntimeException("reverse: \n" +
+ expected + " \n" + actual);
+ }
+ }
+
+ for (int i = 0; i < N; i++) {
+ long x = rnd.nextLong();
if (highestOneBit(x) != reverse(lowestOneBit(reverse(x))))
throw new RuntimeException("g: " + toHexString(x));
}
@@ -136,4 +151,12 @@
throw new RuntimeException("z: " + toHexString(x));
}
}
+
+ private static String leftpad(String s, int width) {
+ String r = s;
+ for (int c = 0; c < width - s.length(); c++) {
+ r = "0" + r;
+ }
+ return r;
+ }
}