This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-fury.git


The following commit(s) were added to refs/heads/main by this push:
     new 4c60eb97 feat(java): optimize read char/short jvm jit inline (#1471)
4c60eb97 is described below

commit 4c60eb9780ec51ffe1aac3ee2da594c0762799e0
Author: Shawn Yang <shawn.ck.y...@gmail.com>
AuthorDate: Sat Apr 6 19:53:53 2024 +0800

    feat(java): optimize read char/short jvm jit inline (#1471)
    
    - optimize read char jvm jit inline by separate little/big endian
    methods
    - optimize read short jvm jit inline by separate little/big endian
    methods
    - generate unsafe get short code online
    - generate unsafe get char code online
---
 .../fury/builder/BaseObjectCodecBuilder.java       |   5 +-
 .../java/org/apache/fury/builder/CodecBuilder.java |  23 ++++-
 .../java/org/apache/fury/memory/MemoryBuffer.java  | 111 +++++++++++----------
 .../org/apache/fury/memory/MemoryBufferTest.java   |   2 +-
 4 files changed, 84 insertions(+), 57 deletions(-)

diff --git 
a/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java
 
b/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java
index a27abbab..f92e076e 100644
--- 
a/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java
+++ 
b/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java
@@ -40,7 +40,6 @@ import static 
org.apache.fury.type.TypeUtils.PRIMITIVE_BYTE_TYPE;
 import static org.apache.fury.type.TypeUtils.PRIMITIVE_DOUBLE_TYPE;
 import static org.apache.fury.type.TypeUtils.PRIMITIVE_FLOAT_TYPE;
 import static org.apache.fury.type.TypeUtils.PRIMITIVE_INT_TYPE;
-import static org.apache.fury.type.TypeUtils.PRIMITIVE_SHORT_TYPE;
 import static org.apache.fury.type.TypeUtils.PRIMITIVE_VOID_TYPE;
 import static org.apache.fury.type.TypeUtils.SET_TYPE;
 import static org.apache.fury.type.TypeUtils.getElementType;
@@ -1131,9 +1130,9 @@ public abstract class BaseObjectCodecBuilder extends 
CodecBuilder {
       } else if (cls == boolean.class || cls == Boolean.class) {
         return new Invoke(buffer, "readBoolean", PRIMITIVE_BOOLEAN_TYPE);
       } else if (cls == char.class || cls == Character.class) {
-        return new Invoke(buffer, "readChar", TypeToken.of(char.class));
+        return readChar(buffer);
       } else if (cls == short.class || cls == Short.class) {
-        return new Invoke(buffer, "readShort", PRIMITIVE_SHORT_TYPE);
+        return readShort(buffer);
       } else if (cls == int.class || cls == Integer.class) {
         return fury.compressInt() ? readVarInt(buffer) : readInt(buffer);
       } else if (cls == long.class || cls == Long.class) {
diff --git 
a/java/fury-core/src/main/java/org/apache/fury/builder/CodecBuilder.java 
b/java/fury-core/src/main/java/org/apache/fury/builder/CodecBuilder.java
index 121c6ecb..746a698d 100644
--- a/java/fury-core/src/main/java/org/apache/fury/builder/CodecBuilder.java
+++ b/java/fury-core/src/main/java/org/apache/fury/builder/CodecBuilder.java
@@ -587,11 +587,20 @@ public abstract class CodecBuilder {
   }
 
   protected Expression unsafeGetChar(Expression base, Expression pos) {
-    return new StaticInvoke(MemoryBuffer.class, "unsafeGetChar", 
PRIMITIVE_CHAR_TYPE, base, pos);
+    StaticInvoke expr = new StaticInvoke(Platform.class, "getChar", 
PRIMITIVE_CHAR_TYPE, base, pos);
+    if (!Platform.IS_LITTLE_ENDIAN) {
+      expr = new StaticInvoke(Character.class, "reverseBytes", 
PRIMITIVE_CHAR_TYPE, expr.inline());
+    }
+    return expr;
   }
 
   protected Expression unsafeGetShort(Expression base, Expression pos) {
-    return new StaticInvoke(MemoryBuffer.class, "unsafeGetShort", 
PRIMITIVE_SHORT_TYPE, base, pos);
+    StaticInvoke expr =
+        new StaticInvoke(Platform.class, "getShort", PRIMITIVE_SHORT_TYPE, 
base, pos);
+    if (!Platform.IS_LITTLE_ENDIAN) {
+      expr = new StaticInvoke(Short.class, "reverseBytes", 
PRIMITIVE_SHORT_TYPE, expr.inline());
+    }
+    return expr;
   }
 
   protected Expression unsafeGetInt(Expression base, Expression pos) {
@@ -619,6 +628,16 @@ public abstract class CodecBuilder {
         MemoryBuffer.class, "unsafeGetDouble", PRIMITIVE_DOUBLE_TYPE, base, 
pos);
   }
 
+  protected Expression readChar(Expression buffer) {
+    String func = Platform.IS_LITTLE_ENDIAN ? "readCharOnLE" : "readCharOnBE";
+    return new Invoke(buffer, func, PRIMITIVE_CHAR_TYPE);
+  }
+
+  protected Expression readShort(Expression buffer) {
+    String func = Platform.IS_LITTLE_ENDIAN ? "readShortOnLE" : 
"readShortOnBE";
+    return new Invoke(buffer, func, PRIMITIVE_SHORT_TYPE);
+  }
+
   protected Expression readInt(Expression buffer) {
     String func = Platform.IS_LITTLE_ENDIAN ? "readIntOnLE" : "readIntOnBE";
     return new Invoke(buffer, func, PRIMITIVE_INT_TYPE);
diff --git 
a/java/fury-core/src/main/java/org/apache/fury/memory/MemoryBuffer.java 
b/java/fury-core/src/main/java/org/apache/fury/memory/MemoryBuffer.java
index 105fcd8c..155b8df6 100644
--- a/java/fury-core/src/main/java/org/apache/fury/memory/MemoryBuffer.java
+++ b/java/fury-core/src/main/java/org/apache/fury/memory/MemoryBuffer.java
@@ -505,33 +505,6 @@ public final class MemoryBuffer {
     }
   }
 
-  public char unsafeGetCharN(int index) {
-    final long pos = address + index;
-    return UNSAFE.getChar(heapMemory, pos);
-  }
-
-  public char unsafeGetChar(int index) {
-    final long pos = address + index;
-    if (LITTLE_ENDIAN) {
-      return UNSAFE.getChar(heapMemory, pos);
-    } else {
-      return Character.reverseBytes(UNSAFE.getChar(heapMemory, pos));
-    }
-  }
-
-  public static char unsafeGetChar(Object o, long pos) {
-    if (LITTLE_ENDIAN) {
-      return UNSAFE.getChar(o, pos);
-    } else {
-      return Character.reverseBytes(UNSAFE.getChar(o, pos));
-    }
-  }
-
-  public void unsafePutCharN(int index, char value) {
-    final long pos = address + index;
-    UNSAFE.putChar(heapMemory, pos, value);
-  }
-
   public void unsafePutChar(int index, char value) {
     final long pos = address + index;
     if (LITTLE_ENDIAN) {
@@ -549,12 +522,6 @@ public final class MemoryBuffer {
     }
   }
 
-  public short getShortN(int index) {
-    final long pos = address + index;
-    checkPosition(index, pos, 2);
-    return UNSAFE.getShort(heapMemory, pos);
-  }
-
   /** Get short in big endian order from provided buffer. */
   public static short getShortB(byte[] b, int off) {
     return (short) ((b[off + 1] & 0xFF) + (b[off] << 8));
@@ -597,11 +564,6 @@ public final class MemoryBuffer {
     }
   }
 
-  public short unsafeGetShortN(int index) {
-    final long pos = address + index;
-    return UNSAFE.getShort(heapMemory, pos);
-  }
-
   public short unsafeGetShort(int index) {
     final long pos = address + index;
     if (LITTLE_ENDIAN) {
@@ -611,19 +573,6 @@ public final class MemoryBuffer {
     }
   }
 
-  public static short unsafeGetShort(Object o, long offset) {
-    if (LITTLE_ENDIAN) {
-      return UNSAFE.getShort(o, offset);
-    } else {
-      return Short.reverseBytes(UNSAFE.getShort(o, offset));
-    }
-  }
-
-  public void unsafePutShortN(int index, short value) {
-    final long pos = address + index;
-    UNSAFE.putShort(heapMemory, pos, value);
-  }
-
   public void unsafePutShort(int index, short value) {
     final long pos = address + index;
     if (LITTLE_ENDIAN) {
@@ -2131,6 +2080,36 @@ public final class MemoryBuffer {
     }
   }
 
+  // Reduce method body for better inline in the caller.
+  @CodegenInvoke
+  public char readCharOnLE() {
+    int readerIdx = readerIndex;
+    // use subtract to avoid overflow
+    int remaining = size - readerIdx;
+    if (remaining < 2) {
+      throw new IndexOutOfBoundsException(
+          String.format(
+              "readerIndex(%d) + length(%d) exceeds size(%d): %s", readerIdx, 
2, size, this));
+    }
+    readerIndex = readerIdx + 2;
+    return UNSAFE.getChar(heapMemory, address + readerIdx);
+  }
+
+  // Reduce method body for better inline in the caller.
+  @CodegenInvoke
+  public char readCharOnBE() {
+    int readerIdx = readerIndex;
+    // use subtract to avoid overflow
+    int remaining = size - readerIdx;
+    if (remaining < 2) {
+      throw new IndexOutOfBoundsException(
+          String.format(
+              "readerIndex(%d) + length(%d) exceeds size(%d): %s", readerIdx, 
2, size, this));
+    }
+    readerIndex = readerIdx + 2;
+    return Character.reverseBytes(UNSAFE.getChar(heapMemory, address + 
readerIdx));
+  }
+
   public short readShort() {
     int readerIdx = readerIndex;
     // use subtract to avoid overflow
@@ -2148,6 +2127,36 @@ public final class MemoryBuffer {
     }
   }
 
+  // Reduce method body for better inline in the caller.
+  @CodegenInvoke
+  public short readShortOnLE() {
+    int readerIdx = readerIndex;
+    // use subtract to avoid overflow
+    int remaining = size - readerIdx;
+    if (remaining < 2) {
+      throw new IndexOutOfBoundsException(
+          String.format(
+              "readerIndex(%d) + length(%d) exceeds size(%d): %s", readerIdx, 
2, size, this));
+    }
+    readerIndex = readerIdx + 2;
+    return UNSAFE.getShort(heapMemory, address + readerIdx);
+  }
+
+  // Reduce method body for better inline in the caller.
+  @CodegenInvoke
+  public short readShortOnBE() {
+    int readerIdx = readerIndex;
+    // use subtract to avoid overflow
+    int remaining = size - readerIdx;
+    if (remaining < 2) {
+      throw new IndexOutOfBoundsException(
+          String.format(
+              "readerIndex(%d) + length(%d) exceeds size(%d): %s", readerIdx, 
2, size, this));
+    }
+    readerIndex = readerIdx + 2;
+    return Short.reverseBytes(UNSAFE.getShort(heapMemory, address + 
readerIdx));
+  }
+
   public int readInt() {
     int readerIdx = readerIndex;
     // use subtract to avoid overflow
diff --git 
a/java/fury-core/src/test/java/org/apache/fury/memory/MemoryBufferTest.java 
b/java/fury-core/src/test/java/org/apache/fury/memory/MemoryBufferTest.java
index 6b1cc7fa..78fa41ba 100644
--- a/java/fury-core/src/test/java/org/apache/fury/memory/MemoryBufferTest.java
+++ b/java/fury-core/src/test/java/org/apache/fury/memory/MemoryBufferTest.java
@@ -83,7 +83,7 @@ public class MemoryBufferTest {
       pos -= 4;
       assertEquals(MemoryBuffer.unsafeGetInt(heapMemory, pos), 
Integer.MIN_VALUE);
       pos -= 2;
-      assertEquals(MemoryBuffer.unsafeGetShort(heapMemory, pos), 
Short.MAX_VALUE);
+      assertEquals(buffer.getShort((int) (pos - Platform.BYTE_ARRAY_OFFSET)), 
Short.MAX_VALUE);
       pos -= 1;
       assertEquals(MemoryBuffer.unsafeGet(heapMemory, pos), Byte.MIN_VALUE);
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@fury.apache.org
For additional commands, e-mail: commits-h...@fury.apache.org

Reply via email to