From 3ac0078e2ac28cc88da31df41b501fdbd1c0f111 Mon Sep 17 00:00:00 2001 From: Ivan Hetman Date: Thu, 26 Oct 2023 09:09:08 +0300 Subject: [PATCH] classlib: add cache to Byte and Short valueOf; fix Byte.parseByte (#832) --- .../org/teavm/classlib/java/lang/TByte.java | 16 ++++++++++++---- .../org/teavm/classlib/java/lang/TShort.java | 18 ++++++++++++++++-- .../org/teavm/classlib/java/lang/ByteTest.java | 8 ++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TByte.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TByte.java index ab936b522..1c0bf1fde 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TByte.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TByte.java @@ -21,6 +21,7 @@ public class TByte extends TNumber implements TComparable { public static final Class TYPE = byte.class; public static final int SIZE = 8; public static final int BYTES = 1; + private static TByte[] byteCache = ensureByteCache(); private final byte value; public TByte(byte value) { @@ -56,9 +57,16 @@ public class TByte extends TNumber implements TComparable { return value; } - public static TByte valueOf(byte value) { - // TODO: add caching - return new TByte(value); + public static TByte valueOf(byte i) { + return byteCache[i + 128]; + } + + private static TByte[] ensureByteCache() { + TByte[] byteCache = new TByte[256]; + for (int j = 0; j < byteCache.length; ++j) { + byteCache[j] = new TByte((byte) (j - 128)); + } + return byteCache; } public static String toString(byte value) { @@ -111,7 +119,7 @@ public class TByte extends TNumber implements TComparable { public static byte parseByte(String s, int radix) throws TNumberFormatException { int value = TInteger.parseInt(s, radix); - if (value < MIN_VALUE || value >= MAX_VALUE) { + if (value < MIN_VALUE || value > MAX_VALUE) { throw new TNumberFormatException(); } return (byte) value; diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TShort.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TShort.java index ce43efed7..67738640d 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TShort.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TShort.java @@ -21,6 +21,7 @@ public class TShort extends TNumber implements TComparable { public static final Class TYPE = short.class; public static final int SIZE = 16; public static final int BYTES = SIZE / Byte.SIZE; + private static TShort[] shortCache; private final short value; public TShort(short value) { @@ -56,8 +57,21 @@ public class TShort extends TNumber implements TComparable { return value; } - public static TShort valueOf(short value) { - return new TShort(value); + public static TShort valueOf(short i) { + if (i >= -128 && i <= 127) { + ensureShortCache(); + return shortCache[i + 128]; + } + return new TShort(i); + } + + private static void ensureShortCache() { + if (shortCache == null) { + shortCache = new TShort[256]; + for (int j = 0; j < shortCache.length; ++j) { + shortCache[j] = new TShort((short) (j - 128)); + } + } } public static String toString(short value) { diff --git a/tests/src/test/java/org/teavm/classlib/java/lang/ByteTest.java b/tests/src/test/java/org/teavm/classlib/java/lang/ByteTest.java index 9eafcdf23..48c029cce 100644 --- a/tests/src/test/java/org/teavm/classlib/java/lang/ByteTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/lang/ByteTest.java @@ -16,6 +16,7 @@ package org.teavm.classlib.java.lang; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; @@ -48,4 +49,11 @@ public class ByteTest { public void bytes() { assertEquals(1, Byte.BYTES); } + + @Test + public void cache() { + for (int b = Byte.MIN_VALUE; b <= Byte.MAX_VALUE; b++) { + assertSame(Byte.valueOf((byte) b), (byte) b); + } + } }