Skip to content
Permalink
Browse files
8269246: Scoped ByteBuffer vector access
Reviewed-by: mcimadamore
  • Loading branch information
Paul Sandoz committed Jun 24, 2021
1 parent 3fb28d3 commit 63bcd3336ecf77a8d256b243c13165397fc8e5bb
Showing 42 changed files with 360 additions and 269 deletions.
@@ -31,10 +31,15 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.ref.Reference;
import java.io.FileDescriptor;
import java.nio.Buffer;
import java.nio.ByteBuffer;

import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.foreign.MemorySegmentProxy;
import jdk.internal.util.ArraysSupport;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.vector.VectorSupport;


/**
@@ -334,6 +339,126 @@ public class ScopedMemoryAccess {
Reference.reachabilityFence(scope);
}
}

// ByteBuffer vector access ops

// Buffer access constants, to be initalized when required.
// Avoids a null value for NIO_ACCESS, due to class initalization dependencies
static final class BufferAccess {
// Buffer.address
static final long BUFFER_ADDRESS
= UNSAFE.objectFieldOffset(Buffer.class, "address");

// ByteBuffer.hb
static final long BYTE_BUFFER_HB
= UNSAFE.objectFieldOffset(ByteBuffer.class, "hb");

@ForceInline
static Object bufferBase(ByteBuffer bb) {
return UNSAFE.getReference(bb, BYTE_BUFFER_HB);
}

@ForceInline
static long bufferAddress(ByteBuffer bb, long offset) {
return UNSAFE.getLong(bb, BUFFER_ADDRESS) + offset;
}

static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();

@ForceInline
static ScopedMemoryAccess.Scope scope(ByteBuffer bb) {
MemorySegmentProxy segmentProxy = NIO_ACCESS.bufferSegment(bb);
return segmentProxy != null ?
segmentProxy.scope() : null;
}
}

@ForceInline
public static
<V extends VectorSupport.Vector<E>, E, S extends VectorSupport.VectorSpecies<E>>
V loadFromByteBuffer(Class<? extends V> vmClass, Class<E> e, int length,
ByteBuffer bb, int offset,
S s,
VectorSupport.LoadOperation<ByteBuffer, V, E, S> defaultImpl) {
try {
return loadFromByteBufferScoped(
BufferAccess.scope(bb),
vmClass, e, length,
bb, offset,
s,
defaultImpl);
} catch (ScopedMemoryAccess.Scope.ScopedAccessError ex) {
throw new IllegalStateException("This segment is already closed");
}
}

@Scoped
@ForceInline
private static
<V extends VectorSupport.Vector<E>, E, S extends VectorSupport.VectorSpecies<E>>
V loadFromByteBufferScoped(ScopedMemoryAccess.Scope scope,
Class<? extends V> vmClass, Class<E> e, int length,
ByteBuffer bb, int offset,
S s,
VectorSupport.LoadOperation<ByteBuffer, V, E, S> defaultImpl) {
try {
if (scope != null) {
scope.checkValidState();
}

return VectorSupport.load(vmClass, e, length,
BufferAccess.bufferBase(bb), BufferAccess.bufferAddress(bb, offset),
bb, offset, s,
defaultImpl);
} finally {
Reference.reachabilityFence(scope);
}
}

@ForceInline
public static
<V extends VectorSupport.Vector<E>, E>
void storeIntoByteBuffer(Class<? extends V> vmClass, Class<E> e, int length,
V v,
ByteBuffer bb, int offset,
VectorSupport.StoreVectorOperation<ByteBuffer, V> defaultImpl) {
try {
storeIntoByteBufferScoped(
BufferAccess.scope(bb),
vmClass, e, length,
v,
bb, offset,
defaultImpl);
} catch (ScopedMemoryAccess.Scope.ScopedAccessError ex) {
throw new IllegalStateException("This segment is already closed");
}
}

@Scoped
@ForceInline
private static
<V extends VectorSupport.Vector<E>, E>
void storeIntoByteBufferScoped(ScopedMemoryAccess.Scope scope,
Class<? extends V> vmClass, Class<E> e, int length,
V v,
ByteBuffer bb, int offset,
VectorSupport.StoreVectorOperation<ByteBuffer, V> defaultImpl) {
try {
if (scope != null) {
scope.checkValidState();
}

VectorSupport.store(vmClass, e, length,
BufferAccess.bufferBase(bb), BufferAccess.bufferAddress(bb, offset),
v,
bb, offset,
defaultImpl);
} finally {
Reference.reachabilityFence(scope);
}
}


// typed-ops here

// Note: all the accessor methods defined below take advantage of argument type profiling
@@ -33,6 +33,7 @@
import java.util.function.Function;
import java.util.function.UnaryOperator;

import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.misc.Unsafe;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.vector.VectorSupport;
@@ -3562,15 +3563,14 @@ a, byteArrayAddress(a, offset),
final
ByteVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
ByteSpecies vsp = vspecies();
return VectorSupport.load(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bufferBase(bb), bufferAddress(bb, offset),
bb, offset, vsp,
(buf, off, s) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
return s.ldOp(wb, off,
(wb_, o, i) -> wb_.get(o + i * 1));
});
return ScopedMemoryAccess.loadFromByteBuffer(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bb, offset, vsp,
(buf, off, s) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
return s.ldOp(wb, off,
(wb_, o, i) -> wb_.get(o + i * 1));
});
}

// Unchecked storing operations in native byte order.
@@ -3613,15 +3613,14 @@ a, byteArrayAddress(a, offset),
final
void intoByteBuffer0(ByteBuffer bb, int offset) {
ByteSpecies vsp = vspecies();
VectorSupport.store(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bufferBase(bb), bufferAddress(bb, offset),
this, bb, offset,
(buf, off, v) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
v.stOp(wb, off,
(wb_, o, i, e) -> wb_.put(o + i * 1, e));
});
ScopedMemoryAccess.storeIntoByteBuffer(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
this, bb, offset,
(buf, off, v) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
v.stOp(wb, off,
(wb_, o, i, e) -> wb_.put(o + i * 1, e));
});
}

// End of low-level memory operations.
@@ -33,6 +33,7 @@
import java.util.function.Function;
import java.util.function.UnaryOperator;

import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.misc.Unsafe;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.vector.VectorSupport;
@@ -3173,15 +3174,14 @@ a, byteArrayAddress(a, offset),
final
DoubleVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
DoubleSpecies vsp = vspecies();
return VectorSupport.load(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bufferBase(bb), bufferAddress(bb, offset),
bb, offset, vsp,
(buf, off, s) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
return s.ldOp(wb, off,
(wb_, o, i) -> wb_.getDouble(o + i * 8));
});
return ScopedMemoryAccess.loadFromByteBuffer(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bb, offset, vsp,
(buf, off, s) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
return s.ldOp(wb, off,
(wb_, o, i) -> wb_.getDouble(o + i * 8));
});
}

// Unchecked storing operations in native byte order.
@@ -3224,15 +3224,14 @@ a, byteArrayAddress(a, offset),
final
void intoByteBuffer0(ByteBuffer bb, int offset) {
DoubleSpecies vsp = vspecies();
VectorSupport.store(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bufferBase(bb), bufferAddress(bb, offset),
this, bb, offset,
(buf, off, v) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
v.stOp(wb, off,
(wb_, o, i, e) -> wb_.putDouble(o + i * 8, e));
});
ScopedMemoryAccess.storeIntoByteBuffer(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
this, bb, offset,
(buf, off, v) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
v.stOp(wb, off,
(wb_, o, i, e) -> wb_.putDouble(o + i * 8, e));
});
}

// End of low-level memory operations.
@@ -33,6 +33,7 @@
import java.util.function.Function;
import java.util.function.UnaryOperator;

import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.misc.Unsafe;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.vector.VectorSupport;
@@ -3160,15 +3161,14 @@ a, byteArrayAddress(a, offset),
final
FloatVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
FloatSpecies vsp = vspecies();
return VectorSupport.load(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bufferBase(bb), bufferAddress(bb, offset),
bb, offset, vsp,
(buf, off, s) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
return s.ldOp(wb, off,
(wb_, o, i) -> wb_.getFloat(o + i * 4));
});
return ScopedMemoryAccess.loadFromByteBuffer(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bb, offset, vsp,
(buf, off, s) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
return s.ldOp(wb, off,
(wb_, o, i) -> wb_.getFloat(o + i * 4));
});
}

// Unchecked storing operations in native byte order.
@@ -3211,15 +3211,14 @@ a, byteArrayAddress(a, offset),
final
void intoByteBuffer0(ByteBuffer bb, int offset) {
FloatSpecies vsp = vspecies();
VectorSupport.store(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bufferBase(bb), bufferAddress(bb, offset),
this, bb, offset,
(buf, off, v) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
v.stOp(wb, off,
(wb_, o, i, e) -> wb_.putFloat(o + i * 4, e));
});
ScopedMemoryAccess.storeIntoByteBuffer(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
this, bb, offset,
(buf, off, v) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
v.stOp(wb, off,
(wb_, o, i, e) -> wb_.putFloat(o + i * 4, e));
});
}

// End of low-level memory operations.
@@ -33,6 +33,7 @@
import java.util.function.Function;
import java.util.function.UnaryOperator;

import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.misc.Unsafe;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.vector.VectorSupport;
@@ -3269,15 +3270,14 @@ a, byteArrayAddress(a, offset),
final
IntVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
IntSpecies vsp = vspecies();
return VectorSupport.load(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bufferBase(bb), bufferAddress(bb, offset),
bb, offset, vsp,
(buf, off, s) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
return s.ldOp(wb, off,
(wb_, o, i) -> wb_.getInt(o + i * 4));
});
return ScopedMemoryAccess.loadFromByteBuffer(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bb, offset, vsp,
(buf, off, s) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
return s.ldOp(wb, off,
(wb_, o, i) -> wb_.getInt(o + i * 4));
});
}

// Unchecked storing operations in native byte order.
@@ -3320,15 +3320,14 @@ a, byteArrayAddress(a, offset),
final
void intoByteBuffer0(ByteBuffer bb, int offset) {
IntSpecies vsp = vspecies();
VectorSupport.store(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
bufferBase(bb), bufferAddress(bb, offset),
this, bb, offset,
(buf, off, v) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
v.stOp(wb, off,
(wb_, o, i, e) -> wb_.putInt(o + i * 4, e));
});
ScopedMemoryAccess.storeIntoByteBuffer(
vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
this, bb, offset,
(buf, off, v) -> {
ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
v.stOp(wb, off,
(wb_, o, i, e) -> wb_.putInt(o + i * 4, e));
});
}

// End of low-level memory operations.

0 comments on commit 63bcd33

Please sign in to comment.