From 1e4cad312272600ef093e781d740ae48296ab458 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Sun, 16 Nov 2025 02:38:40 +0100 Subject: [PATCH 1/2] Faster implementation of long and int rotation Co-authored-by: Thomas May --- .../google/gwt/emul/java/lang/Integer.java | 23 +++++++------------ .../com/google/gwt/emul/java/lang/Long.java | 23 +++++++------------ .../gwt/emultest/java/lang/IntegerTest.java | 6 +++++ .../gwt/emultest/java/lang/LongTest.java | 6 +++++ 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/user/super/com/google/gwt/emul/java/lang/Integer.java b/user/super/com/google/gwt/emul/java/lang/Integer.java index a56e31e4234..7d4d26c03c8 100644 --- a/user/super/com/google/gwt/emul/java/lang/Integer.java +++ b/user/super/com/google/gwt/emul/java/lang/Integer.java @@ -184,24 +184,17 @@ public static int reverseBytes(int i) { } public static int rotateLeft(int i, int distance) { - while (distance-- > 0) { - i = i << 1 | ((i < 0) ? 1 : 0); - } - return i; + int rotateValue = distance % SIZE; + int lowerBits = i >>> (SIZE - rotateValue); + int upperBits = i << rotateValue; + return upperBits | lowerBits; } public static int rotateRight(int i, int distance) { - int ui = i & MAX_VALUE; // avoid sign extension - int carry = (i < 0) ? 0x40000000 : 0; // MIN_VALUE rightshifted 1 - while (distance-- > 0) { - int nextcarry = ui & 1; - ui = carry | (ui >> 1); - carry = (nextcarry == 0) ? 0 : 0x40000000; - } - if (carry != 0) { - ui = ui | MIN_VALUE; - } - return ui; + int rotateValue = distance % SIZE; + int upperBits = i << (SIZE - rotateValue); + int lowerBits = i >>> rotateValue; + return upperBits | lowerBits; } public static int signum(int i) { diff --git a/user/super/com/google/gwt/emul/java/lang/Long.java b/user/super/com/google/gwt/emul/java/lang/Long.java index 8950a41236f..94371a1a1c5 100644 --- a/user/super/com/google/gwt/emul/java/lang/Long.java +++ b/user/super/com/google/gwt/emul/java/lang/Long.java @@ -128,24 +128,17 @@ public static long reverseBytes(long l) { } public static long rotateLeft(long i, int distance) { - while (distance-- > 0) { - i = i << 1 | ((i < 0) ? 1 : 0); - } - return i; + int rotateValue = distance % SIZE; + long lowerBits = i >>> (SIZE - rotateValue); + long upperBits = i << rotateValue; + return upperBits | lowerBits; } public static long rotateRight(long i, int distance) { - long ui = i & MAX_VALUE; // avoid sign extension - long carry = (i < 0) ? 0x4000000000000000L : 0; // MIN_VALUE rightshifted 1 - while (distance-- > 0) { - long nextcarry = ui & 1; - ui = carry | (ui >> 1); - carry = (nextcarry == 0) ? 0 : 0x4000000000000000L; - } - if (carry != 0) { - ui = ui | MIN_VALUE; - } - return ui; + int rotateValue = distance % SIZE; + long upperBits = i << (SIZE - rotateValue); + long lowerBits = i >>> rotateValue; + return upperBits | lowerBits; } public static int signum(long i) { diff --git a/user/test/com/google/gwt/emultest/java/lang/IntegerTest.java b/user/test/com/google/gwt/emultest/java/lang/IntegerTest.java index 4f93f55aa99..64c9d1395e3 100644 --- a/user/test/com/google/gwt/emultest/java/lang/IntegerTest.java +++ b/user/test/com/google/gwt/emultest/java/lang/IntegerTest.java @@ -234,6 +234,9 @@ public void testRotateLeft() { assertEquals(-1, Integer.rotateLeft(-1, 4)); assertEquals(Integer.MIN_VALUE, Integer.rotateLeft(0x40000000, 1)); assertEquals(1, Integer.rotateLeft(Integer.MIN_VALUE, 1)); + assertEquals(Integer.MIN_VALUE, Integer.rotateLeft(Integer.MIN_VALUE, 0)); + assertEquals(Integer.MIN_VALUE, Integer.rotateLeft(1, -1)); + assertEquals(-1, Integer.rotateLeft(-1, 1000)); } public void testRotateRight() { @@ -241,6 +244,9 @@ public void testRotateRight() { assertEquals(Integer.MIN_VALUE, Integer.rotateRight(1, 1)); assertEquals(0x10000000, Integer.rotateRight(1, 4)); assertEquals(-1, Integer.rotateRight(-1, 4)); + assertEquals(Integer.MIN_VALUE, Integer.rotateLeft(Integer.MIN_VALUE, 0)); + assertEquals(1, Integer.rotateRight(Integer.MIN_VALUE, -1)); + assertEquals(-1, Integer.rotateRight(-1, 1000)); } public void testSignum() { diff --git a/user/test/com/google/gwt/emultest/java/lang/LongTest.java b/user/test/com/google/gwt/emultest/java/lang/LongTest.java index 37fb27d6346..d4f30a8b2b5 100644 --- a/user/test/com/google/gwt/emultest/java/lang/LongTest.java +++ b/user/test/com/google/gwt/emultest/java/lang/LongTest.java @@ -224,6 +224,9 @@ public void testRotateLeft() { assertEquals(-1, Long.rotateLeft(-1, 4)); assertEquals(Long.MIN_VALUE, Long.rotateLeft(0x4000000000000000L, 1)); assertEquals(1, Long.rotateLeft(Long.MIN_VALUE, 1)); + assertEquals(Long.MIN_VALUE, Long.rotateLeft(Long.MIN_VALUE, 0)); + assertEquals(Long.MIN_VALUE, Long.rotateLeft(1, -1)); + assertEquals(-1, Long.rotateLeft(-1, 1000)); } public void testRotateRight() { @@ -231,6 +234,9 @@ public void testRotateRight() { assertEquals(Long.MIN_VALUE, Long.rotateRight(1, 1)); assertEquals(0x1000000000000000L, Long.rotateRight(1, 4)); assertEquals(-1, Long.rotateRight(-1, 4)); + assertEquals(Long.MIN_VALUE, Long.rotateRight(Long.MIN_VALUE, 0)); + assertEquals(1, Long.rotateRight(Long.MIN_VALUE, -1)); + assertEquals(-1, Long.rotateRight(-1, 1000)); } public void testSignum() { From 0bfc1ac3d2cdd8553983088bd2064f89e41b0965 Mon Sep 17 00:00:00 2001 From: Zbynek Konecny Date: Mon, 17 Nov 2025 11:18:17 +0100 Subject: [PATCH 2/2] Remove unused mod operation --- user/super/com/google/gwt/emul/java/lang/Integer.java | 10 ++++------ user/super/com/google/gwt/emul/java/lang/Long.java | 10 ++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/user/super/com/google/gwt/emul/java/lang/Integer.java b/user/super/com/google/gwt/emul/java/lang/Integer.java index 7d4d26c03c8..d349bdab092 100644 --- a/user/super/com/google/gwt/emul/java/lang/Integer.java +++ b/user/super/com/google/gwt/emul/java/lang/Integer.java @@ -184,16 +184,14 @@ public static int reverseBytes(int i) { } public static int rotateLeft(int i, int distance) { - int rotateValue = distance % SIZE; - int lowerBits = i >>> (SIZE - rotateValue); - int upperBits = i << rotateValue; + int lowerBits = i >>> (SIZE - distance); + int upperBits = i << distance; return upperBits | lowerBits; } public static int rotateRight(int i, int distance) { - int rotateValue = distance % SIZE; - int upperBits = i << (SIZE - rotateValue); - int lowerBits = i >>> rotateValue; + int upperBits = i << (SIZE - distance); + int lowerBits = i >>> distance; return upperBits | lowerBits; } diff --git a/user/super/com/google/gwt/emul/java/lang/Long.java b/user/super/com/google/gwt/emul/java/lang/Long.java index 94371a1a1c5..33622aa6b4f 100644 --- a/user/super/com/google/gwt/emul/java/lang/Long.java +++ b/user/super/com/google/gwt/emul/java/lang/Long.java @@ -128,16 +128,14 @@ public static long reverseBytes(long l) { } public static long rotateLeft(long i, int distance) { - int rotateValue = distance % SIZE; - long lowerBits = i >>> (SIZE - rotateValue); - long upperBits = i << rotateValue; + long lowerBits = i >>> (SIZE - distance); + long upperBits = i << distance; return upperBits | lowerBits; } public static long rotateRight(long i, int distance) { - int rotateValue = distance % SIZE; - long upperBits = i << (SIZE - rotateValue); - long lowerBits = i >>> rotateValue; + long upperBits = i << (SIZE - distance); + long lowerBits = i >>> distance; return upperBits | lowerBits; }