diff --git a/dhfs-parent/dhfs-app/src/test/java/com/usatiuk/dhfsapp/integration/DhfsImage.java b/dhfs-parent/dhfs-app/src/test/java/com/usatiuk/dhfsapp/integration/DhfsImage.java index 9fa434f7..5995c64f 100644 --- a/dhfs-parent/dhfs-app/src/test/java/com/usatiuk/dhfsapp/integration/DhfsImage.java +++ b/dhfs-parent/dhfs-app/src/test/java/com/usatiuk/dhfsapp/integration/DhfsImage.java @@ -70,6 +70,7 @@ public class DhfsImage implements Future { "--add-exports", "java.base/sun.nio.ch=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.access=ALL-UNNAMED", "--add-opens=java.base/java.nio=ALL-UNNAMED", + "--enable-preview", "-Ddhfs.objects.peerdiscovery.interval=1s", "-Ddhfs.objects.invalidation.delay=100", "-Ddhfs.objects.deletion.delay=0", diff --git a/dhfs-parent/objects/src/main/java/com/usatiuk/objects/JObjectKeyImpl.java b/dhfs-parent/objects/src/main/java/com/usatiuk/objects/JObjectKeyImpl.java index 584c35b5..b6ff0f31 100644 --- a/dhfs-parent/objects/src/main/java/com/usatiuk/objects/JObjectKeyImpl.java +++ b/dhfs-parent/objects/src/main/java/com/usatiuk/objects/JObjectKeyImpl.java @@ -46,7 +46,7 @@ public final class JObjectKeyImpl implements JObjectKey { synchronized (this) { if (_bb != null) return _bb; var bytes = value.getBytes(StandardCharsets.ISO_8859_1); - var directBb = ByteBuffer.allocateDirect(bytes.length); + var directBb = UninitializedByteBuffer.allocate(bytes.length); directBb.put(bytes); directBb.flip(); _bb = directBb; diff --git a/dhfs-parent/pom.xml b/dhfs-parent/pom.xml index 2fa02021..fe3ab053 100644 --- a/dhfs-parent/pom.xml +++ b/dhfs-parent/pom.xml @@ -102,6 +102,7 @@ -parameters --add-exports java.base/jdk.internal.access=ALL-UNNAMED + --enable-preview @@ -119,6 +120,7 @@ --add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-exports java.base/jdk.internal.access=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED + --enable-preview ${skip.unit} true diff --git a/dhfs-parent/utils/src/main/java/com/usatiuk/utils/UninitializedByteBuffer.java b/dhfs-parent/utils/src/main/java/com/usatiuk/utils/UninitializedByteBuffer.java new file mode 100644 index 00000000..a5ff97bb --- /dev/null +++ b/dhfs-parent/utils/src/main/java/com/usatiuk/utils/UninitializedByteBuffer.java @@ -0,0 +1,44 @@ +package com.usatiuk.utils; + +import java.lang.foreign.*; +import java.lang.invoke.MethodHandle; +import java.nio.ByteBuffer; +import java.util.function.Consumer; + +public class UninitializedByteBuffer { + private static final Linker LINKER = Linker.nativeLinker(); + private static final MethodHandle malloc = LINKER.downcallHandle( + LINKER.defaultLookup().find("malloc").orElseThrow(), + FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.JAVA_LONG) + ); + private static final MethodHandle free = LINKER.downcallHandle( + LINKER.defaultLookup().find("free").orElseThrow(), + FunctionDescriptor.ofVoid(ValueLayout.ADDRESS) + ); + + public static ByteBuffer allocate(int capacity) { + UnsafeAccessor.get().getNioAccess().reserveMemory(capacity, capacity); + + MemorySegment segment = null; + try { + segment = (MemorySegment) malloc.invokeExact((long) capacity); + } catch (Throwable e) { + throw new RuntimeException(e); + } + + Consumer cleanup = s -> { + try { + free.invokeExact(s); + UnsafeAccessor.get().getNioAccess().unreserveMemory(capacity, capacity); + } catch (Throwable e) { + throw new RuntimeException(e); + } + }; + var reint = segment.reinterpret(capacity, Arena.ofAuto(), cleanup); + return reint.asByteBuffer(); + } + + public static long getAddress(ByteBuffer buffer) { + return UnsafeAccessor.get().getNioAccess().getBufferAddress(buffer); + } +}