Skip to content

Instantly share code, notes, and snippets.

@mcimadamore
Created October 13, 2021 11:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcimadamore/c2c7e1943ebbdcb4dd846185831984c0 to your computer and use it in GitHub Desktop.
Save mcimadamore/c2c7e1943ebbdcb4dd846185831984c0 to your computer and use it in GitHub Desktop.
A malloc allocator which doesn't zero memory
import jdk.incubator.foreign.Addressable;
import jdk.incubator.foreign.CLinker;
import jdk.incubator.foreign.FunctionDescriptor;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.ResourceScope;
import jdk.incubator.foreign.SegmentAllocator;
import jdk.incubator.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
class Malloc implements SegmentAllocator {
private final ResourceScope scope;
public Malloc(ResourceScope scope) {
this.scope = scope;
}
@Override
public MemorySegment allocate(long bytesSize, long bytesAlignment) {
MemoryAddress ptr = allocateMemory(bytesAlignment, bytesSize);
if (ptr.equals(MemoryAddress.NULL)) {
throw new IllegalArgumentException();
}
try {
scope.addCloseAction(() -> freeMemory(ptr));
return MemorySegment.ofAddressNative(ptr, bytesSize, scope);
} catch (IllegalStateException ex) {
freeMemory(ptr);
throw ex;
}
}
private static CLinker LINKER = CLinker.systemCLinker();
private static final MethodHandle FREE = LINKER.downcallHandle(
LINKER.lookup("free").get(), FunctionDescriptor.ofVoid(ValueLayout.ADDRESS));
private static final MethodHandle ALIGNED_MALLOC = LINKER.downcallHandle(
LINKER.lookup("aligned_alloc").get(), FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG));
private static void freeMemory(Addressable address) {
try {
FREE.invokeExact(address);
} catch (Throwable ex) {
throw new IllegalStateException(ex);
}
}
private static MemoryAddress allocateMemory(long alignment, long size) {
try {
return (MemoryAddress)ALIGNED_MALLOC.invokeExact(alignment, size);
} catch (Throwable ex) {
throw new IllegalStateException(ex);
}
}
public static void main(String[] args) {
MemorySegment segment;
try (var scope = ResourceScope.newConfinedScope()) {
SegmentAllocator malloc = new Malloc(scope);
segment = malloc.allocate(100);
System.out.println(segment);
}
}
}
@leerho
Copy link

leerho commented Oct 13, 2021

Thank you for this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment