Skip to content

Commit

Permalink
Replace Unsafe with VarHandle for sip hash calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Dec 11, 2024
1 parent e1ee3b7 commit 2923805
Showing 1 changed file with 4 additions and 51 deletions.
55 changes: 4 additions & 51 deletions core/src/main/java/org/jruby/util/SipHashInline.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package org.jruby.util;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;

import org.jruby.util.unsafe.UnsafeHolder;

import sun.misc.Unsafe;

/**
* SipHash implementation with hand inlining the SIPROUND.
*
Expand Down Expand Up @@ -37,7 +35,7 @@ public static long hash24(long k0, long k1, byte[] src, int offset, int length)

// processing 8 bytes blocks in data
while (i < last) {
m = LongReader.INSTANCE.getLong(src, i);
m = (long) BYTE_ARRAY_HANDLE.get(src, i);
i += 8;
// MSGROUND {
v3 ^= m;
Expand Down Expand Up @@ -145,50 +143,5 @@ public static long hash24(long k0, long k1, byte[] src, int offset, int length)
return v0 ^ v1 ^ v2 ^ v3;
}

private static abstract class LongReader {
public abstract long getLong(byte[] src, int offset);

public static final LongReader INSTANCE = createBestLongReader();

private static LongReader createBestLongReader() {
try {
if (UnsafeHolder.U != null) {
if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
return new UnsafeLongReader(UnsafeHolder.U);
}
}
} catch (Exception e) {
}
return new FallbackLongReader();
}

private static final class FallbackLongReader extends LongReader {
@Override
public long getLong(byte[] src, int offset) {
return (long) src[offset++] |
(long) src[offset++] << 8 |
(long) src[offset++] << 16 |
(long) src[offset++] << 24 |
(long) src[offset++] << 32 |
(long) src[offset++] << 40 |
(long) src[offset++] << 48 |
(long) src[offset++] << 56 ;
}
}

private static final class UnsafeLongReader extends LongReader {
final Unsafe unsafe;
final int byteArrayBaseOffset;

public UnsafeLongReader(Unsafe unsafe) {
this.unsafe = unsafe;
this.byteArrayBaseOffset = unsafe.arrayBaseOffset(byte[].class);
}

@Override
public final long getLong(byte[] src, int offset) {
return unsafe.getLong(src, byteArrayBaseOffset + (long)offset);
}
}
}
static final VarHandle BYTE_ARRAY_HANDLE = MethodHandles.byteArrayViewVarHandle(long[].class, ByteOrder.nativeOrder());
}

0 comments on commit 2923805

Please sign in to comment.