8254162: Implementation of Foreign-Memory Access API (Third Incubator)

Reviewed-by: erikj, psandoz, alanb
This commit is contained in:
Maurizio Cimadamore 2020-11-12 16:37:23 +00:00
parent c6ab0fdb15
commit 3e70aac5cc
82 changed files with 6038 additions and 2837 deletions

View file

@ -36,28 +36,21 @@ abstract class MemoryAccessVarHandleBase extends VarHandle {
/** access size (in bytes, computed from var handle carrier type) **/
final long length;
/** access offset (in bytes); must be compatible with {@code alignmentMask} **/
final long offset;
/** alignment constraint (in bytes, expressed as a bit mask) **/
final long alignmentMask;
MemoryAccessVarHandleBase(VarForm form, boolean be, long length, long offset, long alignmentMask, boolean exact) {
/** if true, only the base part of the address will be checked for alignment **/
final boolean skipAlignmentMaskCheck;
MemoryAccessVarHandleBase(VarForm form, boolean skipAlignmentMaskCheck, boolean be, long length, long alignmentMask, boolean exact) {
super(form, exact);
this.skipAlignmentMaskCheck = skipAlignmentMaskCheck;
this.be = be;
this.length = length;
this.offset = offset;
this.alignmentMask = alignmentMask;
}
static IllegalStateException newIllegalStateExceptionForMisalignedAccess(long address) {
return new IllegalStateException("Misaligned access at address: " + address);
}
/**
* Strides used for multi-dimensional access; each stride must be compatible with {@code alignmentMask}.
*/
abstract long[] strides();
abstract Class<?> carrier();
}

View file

@ -1,554 +0,0 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang.invoke;
import jdk.internal.access.foreign.MemoryAddressProxy;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.ConstantDynamic;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.internal.org.objectweb.asm.util.TraceClassVisitor;
import jdk.internal.vm.annotation.ForceInline;
import sun.security.action.GetBooleanAction;
import sun.security.action.GetPropertyAction;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashMap;
import static jdk.internal.org.objectweb.asm.Opcodes.AALOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN;
import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE;
import static jdk.internal.org.objectweb.asm.Opcodes.BIPUSH;
import static jdk.internal.org.objectweb.asm.Opcodes.CHECKCAST;
import static jdk.internal.org.objectweb.asm.Opcodes.GETFIELD;
import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1;
import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_2;
import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_3;
import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import static jdk.internal.org.objectweb.asm.Opcodes.LALOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.LASTORE;
import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.NEW;
import static jdk.internal.org.objectweb.asm.Opcodes.NEWARRAY;
import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD;
import static jdk.internal.org.objectweb.asm.Opcodes.PUTSTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
import static jdk.internal.org.objectweb.asm.Opcodes.DUP;
import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH;
import static jdk.internal.org.objectweb.asm.Opcodes.T_LONG;
import static jdk.internal.org.objectweb.asm.Opcodes.V14;
class MemoryAccessVarHandleGenerator {
private static final String DEBUG_DUMP_CLASSES_DIR_PROPERTY = "jdk.internal.foreign.ClassGenerator.DEBUG_DUMP_CLASSES_DIR";
private static final boolean DEBUG =
GetBooleanAction.privilegedGetProperty("jdk.internal.foreign.ClassGenerator.DEBUG");
private static final Class<?> BASE_CLASS = MemoryAccessVarHandleBase.class;
private static final HashMap<Class<?>, Class<?>> helperClassCache;
private final static MethodType OFFSET_OP_TYPE;
private final static MethodHandle ADD_OFFSETS_HANDLE;
private final static MethodHandle MUL_OFFSETS_HANDLE;
private final static MethodType CONSTR_TYPE = MethodType.methodType(void.class, VarForm.class,
boolean.class, long.class, long.class, long.class, boolean.class, long[].class);
// MemoryAccessVarHandleBase
private final static MethodType SUPER_CONTR_TYPE = MethodType.methodType(void.class, VarForm.class,
boolean.class, long.class, long.class, long.class, boolean.class);
static {
helperClassCache = new HashMap<>();
helperClassCache.put(byte.class, MemoryAccessVarHandleByteHelper.class);
helperClassCache.put(short.class, MemoryAccessVarHandleShortHelper.class);
helperClassCache.put(char.class, MemoryAccessVarHandleCharHelper.class);
helperClassCache.put(int.class, MemoryAccessVarHandleIntHelper.class);
helperClassCache.put(long.class, MemoryAccessVarHandleLongHelper.class);
helperClassCache.put(float.class, MemoryAccessVarHandleFloatHelper.class);
helperClassCache.put(double.class, MemoryAccessVarHandleDoubleHelper.class);
OFFSET_OP_TYPE = MethodType.methodType(long.class, long.class, long.class, MemoryAddressProxy.class);
try {
ADD_OFFSETS_HANDLE = MethodHandles.Lookup.IMPL_LOOKUP.findStatic(MemoryAddressProxy.class, "addOffsets", OFFSET_OP_TYPE);
MUL_OFFSETS_HANDLE = MethodHandles.Lookup.IMPL_LOOKUP.findStatic(MemoryAddressProxy.class, "multiplyOffsets", OFFSET_OP_TYPE);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
private static final File DEBUG_DUMP_CLASSES_DIR;
static {
String path = GetPropertyAction.privilegedGetProperty(DEBUG_DUMP_CLASSES_DIR_PROPERTY);
if (path == null) {
DEBUG_DUMP_CLASSES_DIR = null;
} else {
DEBUG_DUMP_CLASSES_DIR = new File(path);
}
}
private final String implClassName;
private final int dimensions;
private final Class<?> carrier;
private final Class<?> helperClass;
private final VarForm form;
private final Object[] classData;
MemoryAccessVarHandleGenerator(Class<?> carrier, int dims) {
this.dimensions = dims;
this.carrier = carrier;
Class<?>[] components = new Class<?>[dimensions];
Arrays.fill(components, long.class);
this.form = new VarForm(BASE_CLASS, MemoryAddressProxy.class, carrier, components);
this.helperClass = helperClassCache.get(carrier);
this.implClassName = internalName(helperClass) + dimensions;
// live constants
Class<?>[] intermediate = new Class<?>[dimensions];
Arrays.fill(intermediate, long.class);
this.classData = new Object[] { carrier, intermediate, ADD_OFFSETS_HANDLE, MUL_OFFSETS_HANDLE };
}
/*
* Generate a VarHandle memory access factory.
* The factory has type (ZJJ[J)VarHandle.
*/
MethodHandle generateHandleFactory() {
byte[] classBytes = generateClassBytes();
if (DEBUG_DUMP_CLASSES_DIR != null) {
debugWriteClassToFile(classBytes);
}
try {
MethodHandles.Lookup lookup = MethodHandles.lookup().defineHiddenClassWithClassData(classBytes, classData);
Class<?> implCls = lookup.lookupClass();
Class<?>[] components = new Class<?>[dimensions];
Arrays.fill(components, long.class);
VarForm form = new VarForm(implCls, MemoryAddressProxy.class, carrier, components);
MethodHandle constr = lookup.findConstructor(implCls, CONSTR_TYPE);
constr = MethodHandles.insertArguments(constr, 0, form);
return constr;
} catch (Throwable ex) {
debugPrintClass(classBytes);
throw new AssertionError(ex);
}
}
/*
* Generate a specialized VarHandle class for given carrier
* and access coordinates.
*/
byte[] generateClassBytes() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
if (DEBUG) {
System.out.println("Generating header implementation class");
}
cw.visit(V14, ACC_PUBLIC | ACC_SUPER, implClassName, null, Type.getInternalName(BASE_CLASS), null);
//add dimension fields
for (int i = 0; i < dimensions; i++) {
cw.visitField(ACC_PRIVATE | ACC_FINAL, "dim" + i, "J", null, null);
}
addStaticInitializer(cw);
addConstructor(cw);
addAccessModeTypeMethod(cw);
addStridesAccessor(cw);
addCarrierAccessor(cw);
addAsExact(cw);
addAsGeneric(cw);
for (VarHandle.AccessMode mode : VarHandle.AccessMode.values()) {
addAccessModeMethodIfNeeded(mode, cw);
}
cw.visitEnd();
return cw.toByteArray();
}
void addStaticInitializer(ClassWriter cw) {
// carrier and intermediate
cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "carrier", Class.class.descriptorString(), null, null);
cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "intermediate", Class[].class.descriptorString(), null, null);
cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "addHandle", MethodHandle.class.descriptorString(), null, null);
cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "mulHandle", MethodHandle.class.descriptorString(), null, null);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
// extract class data in static final fields
MethodType mtype = MethodType.methodType(Object.class, MethodHandles.Lookup.class, String.class, Class.class);
Handle bsm = new Handle(H_INVOKESTATIC, Type.getInternalName(MethodHandles.class), "classData",
mtype.descriptorString(), false);
ConstantDynamic dynamic = new ConstantDynamic("classData", Object[].class.descriptorString(), bsm);
mv.visitLdcInsn(dynamic);
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Object[].class));
mv.visitVarInsn(ASTORE, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(ICONST_0);
mv.visitInsn(AALOAD);
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Class.class));
mv.visitFieldInsn(PUTSTATIC, implClassName, "carrier", Class.class.descriptorString());
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(ICONST_1);
mv.visitInsn(AALOAD);
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Class[].class));
mv.visitFieldInsn(PUTSTATIC, implClassName, "intermediate", Class[].class.descriptorString());
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(ICONST_2);
mv.visitInsn(AALOAD);
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(MethodHandle.class));
mv.visitFieldInsn(PUTSTATIC, implClassName, "addHandle", MethodHandle.class.descriptorString());
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(ICONST_3);
mv.visitInsn(AALOAD);
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(MethodHandle.class));
mv.visitFieldInsn(PUTSTATIC, implClassName, "mulHandle", MethodHandle.class.descriptorString());
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
void addConstructor(ClassWriter cw) {
MethodVisitor mv = cw.visitMethod(0, "<init>", CONSTR_TYPE.toMethodDescriptorString(), null, null);
mv.visitCode();
//super call
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1); // vform
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(VarForm.class));
mv.visitVarInsn(ILOAD, 2); // be
mv.visitVarInsn(LLOAD, 3); // length
mv.visitVarInsn(LLOAD, 5); // offset
mv.visitVarInsn(LLOAD, 7); // alignmentMask
mv.visitVarInsn(ILOAD, 9); // exact
mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(BASE_CLASS), "<init>",
SUPER_CONTR_TYPE.toMethodDescriptorString(), false);
//init dimensions
for (int i = 0 ; i < dimensions ; i++) {
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 10);
mv.visitLdcInsn(i);
mv.visitInsn(LALOAD);
mv.visitFieldInsn(PUTFIELD, implClassName, "dim" + i, "J");
}
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
void addAccessModeTypeMethod(ClassWriter cw) {
MethodType modeMethType = MethodType.methodType(MethodType.class, VarHandle.AccessType.class);
MethodVisitor mv = cw.visitMethod(ACC_FINAL, "accessModeTypeUncached", modeMethType.toMethodDescriptorString(), null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 1);
mv.visitLdcInsn(Type.getType(MemoryAddressProxy.class));
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Class.class));
mv.visitFieldInsn(GETSTATIC, implClassName, "carrier", Class.class.descriptorString());
mv.visitFieldInsn(GETSTATIC, implClassName, "intermediate", Class[].class.descriptorString());
mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(VarHandle.AccessType.class),
"accessModeType", MethodType.methodType(MethodType.class, Class.class, Class.class, Class[].class).toMethodDescriptorString(), false);
mv.visitInsn(ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
void addAccessModeMethodIfNeeded(VarHandle.AccessMode mode, ClassWriter cw) {
String methName = mode.methodName();
MethodType methType = form.getMethodType(mode.at.ordinal())
.insertParameterTypes(0, VarHandle.class);
try {
MethodType helperType = methType.insertParameterTypes(2, long.class);
if (dimensions > 0) {
helperType = helperType.dropParameterTypes(3, 3 + dimensions);
}
//try to resolve...
String helperMethodName = methName + "0";
MethodHandles.Lookup.IMPL_LOOKUP
.findStatic(helperClass,
helperMethodName,
helperType);
MethodVisitor mv = cw.visitMethod(ACC_STATIC, methName, methType.toMethodDescriptorString(), null, null);
mv.visitAnnotation(Type.getDescriptor(ForceInline.class), true);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0); // handle impl
mv.visitVarInsn(ALOAD, 1); // receiver
// offset calculation
int slot = 2;
mv.visitVarInsn(ALOAD, 0); // load recv
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(BASE_CLASS));
mv.visitFieldInsn(GETFIELD, Type.getInternalName(BASE_CLASS), "offset", "J");
for (int i = 0 ; i < dimensions ; i++) {
// load ADD MH
mv.visitFieldInsn(GETSTATIC, implClassName, "addHandle", MethodHandle.class.descriptorString());
//fixup stack so that ADD MH ends up bottom
mv.visitInsn(Opcodes.DUP_X2);
mv.visitInsn(Opcodes.POP);
// load MUL MH
mv.visitFieldInsn(GETSTATIC, implClassName, "mulHandle", MethodHandle.class.descriptorString());
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(MethodHandle.class));
mv.visitVarInsn(ALOAD, 0); // load recv
mv.visitTypeInsn(CHECKCAST, implClassName);
mv.visitFieldInsn(GETFIELD, implClassName, "dim" + i, "J");
mv.visitVarInsn(LLOAD, slot);
mv.visitVarInsn(ALOAD, 1); // receiver
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(MemoryAddressProxy.class));
//MUL
mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(MethodHandle.class), "invokeExact",
OFFSET_OP_TYPE.toMethodDescriptorString(), false);
mv.visitVarInsn(ALOAD, 1); // receiver
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(MemoryAddressProxy.class));
//ADD
mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(MethodHandle.class), "invokeExact",
OFFSET_OP_TYPE.toMethodDescriptorString(), false);
slot += 2;
}
for (int i = 2 + dimensions; i < methType.parameterCount() ; i++) {
Class<?> param = methType.parameterType(i);
mv.visitVarInsn(loadInsn(param), slot); // load index
slot += getSlotsForType(param);
}
//call helper
mv.visitMethodInsn(INVOKESTATIC, Type.getInternalName(helperClass), helperMethodName,
helperType.toMethodDescriptorString(), false);
mv.visitInsn(returnInsn(helperType.returnType()));
mv.visitMaxs(0, 0);
mv.visitEnd();
} catch (ReflectiveOperationException ex) {
//not found, skip
}
}
void addStridesAccessor(ClassWriter cw) {
MethodVisitor mv = cw.visitMethod(ACC_FINAL, "strides", "()[J", null, null);
mv.visitCode();
iConstInsn(mv, dimensions);
mv.visitIntInsn(NEWARRAY, T_LONG);
for (int i = 0 ; i < dimensions ; i++) {
mv.visitInsn(DUP);
iConstInsn(mv, i);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implClassName, "dim" + i, "J");
mv.visitInsn(LASTORE);
}
mv.visitInsn(ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
void addCarrierAccessor(ClassWriter cw) {
MethodVisitor mv = cw.visitMethod(ACC_FINAL, "carrier", "()Ljava/lang/Class;", null, null);
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, implClassName, "carrier", Class.class.descriptorString());
mv.visitInsn(ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
private void addAsExact(ClassWriter cw) {
addAsExactOrAsGeneric(cw, "asExact", true);
}
private void addAsGeneric(ClassWriter cw) {
addAsExactOrAsGeneric(cw, "asGeneric", false);
}
private void addAsExactOrAsGeneric(ClassWriter cw, String name, boolean exact) {
MethodVisitor mv = cw.visitMethod(ACC_FINAL, name, "()Ljava/lang/invoke/VarHandle;", null, null);
mv.visitCode();
mv.visitTypeInsn(NEW, implClassName);
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, internalName(VarHandle.class), "vform", VarForm.class.descriptorString());
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, internalName(MemoryAccessVarHandleBase.class), "be", boolean.class.descriptorString());
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, internalName(MemoryAccessVarHandleBase.class), "length", long.class.descriptorString());
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, internalName(MemoryAccessVarHandleBase.class), "offset", long.class.descriptorString());
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, internalName(MemoryAccessVarHandleBase.class), "alignmentMask", long.class.descriptorString());
mv.visitIntInsn(BIPUSH, exact ? 1 : 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, implClassName, "strides", "()[J", false);
mv.visitMethodInsn(INVOKESPECIAL, implClassName, "<init>", CONSTR_TYPE.descriptorString(), false);
mv.visitInsn(ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
// shared code generation helpers
private static int getSlotsForType(Class<?> c) {
if (c == long.class || c == double.class) {
return 2;
}
return 1;
}
private static String internalName(Class<?> cls) {
return cls.getName().replace('.', '/');
}
/**
* Emits an actual return instruction conforming to the given return type.
*/
private int returnInsn(Class<?> type) {
return switch (LambdaForm.BasicType.basicType(type)) {
case I_TYPE -> Opcodes.IRETURN;
case J_TYPE -> Opcodes.LRETURN;
case F_TYPE -> Opcodes.FRETURN;
case D_TYPE -> Opcodes.DRETURN;
case L_TYPE -> Opcodes.ARETURN;
case V_TYPE -> RETURN;
};
}
private int loadInsn(Class<?> type) {
return switch (LambdaForm.BasicType.basicType(type)) {
case I_TYPE -> Opcodes.ILOAD;
case J_TYPE -> LLOAD;
case F_TYPE -> Opcodes.FLOAD;
case D_TYPE -> Opcodes.DLOAD;
case L_TYPE -> Opcodes.ALOAD;
case V_TYPE -> throw new IllegalStateException("Cannot load void");
};
}
private static void iConstInsn(MethodVisitor mv, int i) {
switch (i) {
case -1, 0, 1, 2, 3, 4, 5:
mv.visitInsn(ICONST_0 + i);
break;
default:
if(i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, i);
} else if (i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, i);
} else {
mv.visitLdcInsn(i);
}
}
}
// debug helpers
private static String debugPrintClass(byte[] classFile) {
ClassReader cr = new ClassReader(classFile);
StringWriter sw = new StringWriter();
cr.accept(new TraceClassVisitor(new PrintWriter(sw)), 0);
return sw.toString();
}
private void debugWriteClassToFile(byte[] classFile) {
File file = new File(DEBUG_DUMP_CLASSES_DIR, implClassName + ".class");
if (DEBUG) {
System.err.println("Dumping class " + implClassName + " to " + file);
}
try {
debugWriteDataToFile(classFile, file);
} catch (Exception e) {
throw new RuntimeException("Failed to write class " + implClassName + " to file " + file);
}
}
private void debugWriteDataToFile(byte[] data, File file) {
if (file.exists()) {
file.delete();
}
if (file.exists()) {
throw new RuntimeException("Failed to remove pre-existing file " + file);
}
File parent = file.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
if (!parent.exists()) {
throw new RuntimeException("Failed to create " + parent);
}
if (!parent.isDirectory()) {
throw new RuntimeException(parent + " is not a directory");
}
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(data);
} catch (IOException e) {
throw new RuntimeException("Failed to write class " + implClassName + " to file " + file);
}
}
}

View file

@ -1769,40 +1769,9 @@ abstract class MethodHandleImpl {
}
@Override
public VarHandle memoryAccessVarHandle(Class<?> carrier, long alignmentMask,
ByteOrder order, long offset, long[] strides) {
return VarHandles.makeMemoryAddressViewHandle(carrier, alignmentMask, order, offset, strides);
}
@Override
public Class<?> memoryAddressCarrier(VarHandle handle) {
return checkMemoryAccessHandle(handle).carrier();
}
@Override
public long memoryAddressAlignmentMask(VarHandle handle) {
return checkMemoryAccessHandle(handle).alignmentMask;
}
@Override
public ByteOrder memoryAddressByteOrder(VarHandle handle) {
return checkMemoryAccessHandle(handle).be ?
ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
}
@Override
public long memoryAddressOffset(VarHandle handle) {
return checkMemoryAccessHandle(handle).offset;
}
@Override
public long[] memoryAddressStrides(VarHandle handle) {
return checkMemoryAccessHandle(handle).strides();
}
@Override
public boolean isMemoryAccessVarHandle(VarHandle handle) {
return asMemoryAccessVarHandle(handle) != null;
public VarHandle memoryAccessVarHandle(Class<?> carrier, boolean skipAlignmentMaskCheck, long alignmentMask,
ByteOrder order) {
return VarHandles.makeMemoryAddressViewHandle(carrier, skipAlignmentMaskCheck, alignmentMask, order);
}
@Override
@ -1834,26 +1803,6 @@ abstract class MethodHandleImpl {
public VarHandle insertCoordinates(VarHandle target, int pos, Object... values) {
return VarHandles.insertCoordinates(target, pos, values);
}
private MemoryAccessVarHandleBase asMemoryAccessVarHandle(VarHandle handle) {
if (handle instanceof MemoryAccessVarHandleBase) {
return (MemoryAccessVarHandleBase)handle;
} else if (handle.target() instanceof MemoryAccessVarHandleBase) {
// skip first adaptation, since we have to step over MemoryAddressProxy
// see JDK-8237349
return (MemoryAccessVarHandleBase)handle.target();
} else {
return null;
}
}
private MemoryAccessVarHandleBase checkMemoryAccessHandle(VarHandle handle) {
MemoryAccessVarHandleBase base = asMemoryAccessVarHandle(handle);
if (base == null) {
throw new IllegalArgumentException("Not a memory access varhandle: " + handle);
}
return base;
}
});
}

View file

@ -315,30 +315,36 @@ final class VarHandles {
* to a single fixed offset to compute an effective offset from the given MemoryAddress for the access.
*
* @param carrier the Java carrier type.
* @param skipAlignmentMaskCheck if true, only the base part of the address will be checked for alignment.
* @param alignmentMask alignment requirement to be checked upon access. In bytes. Expressed as a mask.
* @param byteOrder the byte order.
* @param offset a constant offset for the access.
* @param strides the scale factors with which to multiply given access coordinates.
* @return the created VarHandle.
*/
static VarHandle makeMemoryAddressViewHandle(Class<?> carrier, long alignmentMask,
ByteOrder byteOrder, long offset, long[] strides) {
static VarHandle makeMemoryAddressViewHandle(Class<?> carrier, boolean skipAlignmentMaskCheck, long alignmentMask,
ByteOrder byteOrder) {
if (!carrier.isPrimitive() || carrier == void.class || carrier == boolean.class) {
throw new IllegalArgumentException("Invalid carrier: " + carrier.getName());
}
long size = Wrapper.forPrimitiveType(carrier).bitWidth() / 8;
boolean be = byteOrder == ByteOrder.BIG_ENDIAN;
boolean exact = false;
Map<Integer, MethodHandle> carrierFactory = ADDRESS_FACTORIES.get(carrier);
MethodHandle fac = carrierFactory.computeIfAbsent(strides.length,
dims -> new MemoryAccessVarHandleGenerator(carrier, dims)
.generateHandleFactory());
try {
boolean exact = false;
return maybeAdapt((VarHandle)fac.invoke(be, size, offset, alignmentMask, exact, strides));
} catch (Throwable ex) {
throw new IllegalStateException(ex);
if (carrier == byte.class) {
return maybeAdapt(new MemoryAccessVarHandleByteHelper(skipAlignmentMaskCheck, be, size, alignmentMask, exact));
} else if (carrier == char.class) {
return maybeAdapt(new MemoryAccessVarHandleCharHelper(skipAlignmentMaskCheck, be, size, alignmentMask, exact));
} else if (carrier == short.class) {
return maybeAdapt(new MemoryAccessVarHandleShortHelper(skipAlignmentMaskCheck, be, size, alignmentMask, exact));
} else if (carrier == int.class) {
return maybeAdapt(new MemoryAccessVarHandleIntHelper(skipAlignmentMaskCheck, be, size, alignmentMask, exact));
} else if (carrier == float.class) {
return maybeAdapt(new MemoryAccessVarHandleFloatHelper(skipAlignmentMaskCheck, be, size, alignmentMask, exact));
} else if (carrier == long.class) {
return maybeAdapt(new MemoryAccessVarHandleLongHelper(skipAlignmentMaskCheck, be, size, alignmentMask, exact));
} else if (carrier == double.class) {
return maybeAdapt(new MemoryAccessVarHandleDoubleHelper(skipAlignmentMaskCheck, be, size, alignmentMask, exact));
} else {
throw new IllegalStateException("Cannot get here");
}
}

View file

@ -27,6 +27,8 @@ package java.lang.invoke;
import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.foreign.MemorySegmentProxy;
import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.misc.ScopedMemoryAccess.Scope;
import jdk.internal.misc.Unsafe;
import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.ForceInline;
@ -41,9 +43,11 @@ import static java.lang.invoke.MethodHandleStatics.UNSAFE;
final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static JavaNioAccess nioAccess = SharedSecrets.getJavaNioAccess();
static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess();
static final int ALIGN = $BoxType$.BYTES - 1;
static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
#if[floatingPoint]
@ForceInline
@ -601,13 +605,17 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
@ForceInline
static int index(ByteBuffer bb, int index) {
MemorySegmentProxy segmentProxy = nioAccess.bufferSegment(bb);
if (segmentProxy != null) {
segmentProxy.checkValidState();
}
MemorySegmentProxy segmentProxy = NIO_ACCESS.bufferSegment(bb);
return Preconditions.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
}
@ForceInline
static Scope scope(ByteBuffer bb) {
MemorySegmentProxy segmentProxy = NIO_ACCESS.bufferSegment(bb);
return segmentProxy != null ?
segmentProxy.scope() : null;
}
@ForceInline
static int indexRO(ByteBuffer bb, int index) {
if (UNSAFE.getBoolean(bb, BYTE_BUFFER_IS_READ_ONLY))
@ -628,13 +636,13 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
#if[floatingPoint]
$rawType$ rawValue = UNSAFE.get$RawType$Unaligned(
$rawType$ rawValue = SCOPED_MEMORY_ACCESS.get$RawType$Unaligned(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
handle.be);
return $Type$.$rawType$BitsTo$Type$(rawValue);
#else[floatingPoint]
return UNSAFE.get$Type$Unaligned(
return SCOPED_MEMORY_ACCESS.get$Type$Unaligned(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
handle.be);
@ -646,13 +654,13 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
#if[floatingPoint]
UNSAFE.put$RawType$Unaligned(
SCOPED_MEMORY_ACCESS.put$RawType$Unaligned(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
$Type$.$type$ToRaw$RawType$Bits(value),
handle.be);
#else[floatingPoint]
UNSAFE.put$Type$Unaligned(
SCOPED_MEMORY_ACCESS.put$Type$Unaligned(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
value,
@ -665,7 +673,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be,
UNSAFE.get$RawType$Volatile(
SCOPED_MEMORY_ACCESS.get$RawType$Volatile(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, index(bb, index))));
}
@ -674,7 +682,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static void setVolatile(VarHandle ob, Object obb, int index, $type$ value) {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
UNSAFE.put$RawType$Volatile(
SCOPED_MEMORY_ACCESS.put$RawType$Volatile(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, value));
@ -685,7 +693,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be,
UNSAFE.get$RawType$Acquire(
SCOPED_MEMORY_ACCESS.get$RawType$Acquire(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, index(bb, index))));
}
@ -694,7 +702,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static void setRelease(VarHandle ob, Object obb, int index, $type$ value) {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
UNSAFE.put$RawType$Release(
SCOPED_MEMORY_ACCESS.put$RawType$Release(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, value));
@ -705,7 +713,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be,
UNSAFE.get$RawType$Opaque(
SCOPED_MEMORY_ACCESS.get$RawType$Opaque(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, index(bb, index))));
}
@ -714,7 +722,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static void setOpaque(VarHandle ob, Object obb, int index, $type$ value) {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
UNSAFE.put$RawType$Opaque(
SCOPED_MEMORY_ACCESS.put$RawType$Opaque(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, value));
@ -726,12 +734,12 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
#if[Object]
return UNSAFE.compareAndSetReference(
return SCOPED_MEMORY_ACCESS.compareAndSetReference(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
#else[Object]
return UNSAFE.compareAndSet$RawType$(
return SCOPED_MEMORY_ACCESS.compareAndSet$RawType$(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -743,7 +751,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be,
UNSAFE.compareAndExchange$RawType$(
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)));
@ -754,7 +762,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be,
UNSAFE.compareAndExchange$RawType$Acquire(
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$Acquire(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)));
@ -765,7 +773,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be,
UNSAFE.compareAndExchange$RawType$Release(
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$Release(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value)));
@ -775,7 +783,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static boolean weakCompareAndSetPlain(VarHandle ob, Object obb, int index, $type$ expected, $type$ value) {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return UNSAFE.weakCompareAndSet$RawType$Plain(
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Plain(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -785,7 +793,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static boolean weakCompareAndSet(VarHandle ob, Object obb, int index, $type$ expected, $type$ value) {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return UNSAFE.weakCompareAndSet$RawType$(
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -795,7 +803,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static boolean weakCompareAndSetAcquire(VarHandle ob, Object obb, int index, $type$ expected, $type$ value) {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return UNSAFE.weakCompareAndSet$RawType$Acquire(
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Acquire(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -805,7 +813,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
static boolean weakCompareAndSetRelease(VarHandle ob, Object obb, int index, $type$ expected, $type$ value) {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return UNSAFE.weakCompareAndSet$RawType$Release(
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Release(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, expected), convEndian(handle.be, value));
@ -817,13 +825,13 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
#if[Object]
return convEndian(handle.be,
UNSAFE.getAndSetReference(
SCOPED_MEMORY_ACCESS.getAndSetReference(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, value)));
#else[Object]
return convEndian(handle.be,
UNSAFE.getAndSet$RawType$(
SCOPED_MEMORY_ACCESS.getAndSet$RawType$(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, value)));
@ -835,7 +843,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be,
UNSAFE.getAndSet$RawType$Acquire(
SCOPED_MEMORY_ACCESS.getAndSet$RawType$Acquire(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, value)));
@ -846,7 +854,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
return convEndian(handle.be,
UNSAFE.getAndSet$RawType$Release(
SCOPED_MEMORY_ACCESS.getAndSet$RawType$Release(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
convEndian(handle.be, value)));
@ -859,7 +867,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndAdd$RawType$(
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
delta);
@ -873,7 +881,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndAdd$RawType$Acquire(
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$Acquire(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
delta);
@ -887,7 +895,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndAdd$RawType$Release(
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$Release(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
delta);
@ -902,7 +910,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
long offset = address(bb, indexRO(bb, index));
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(scope(bb), base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta)));
@ -916,7 +924,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseOr$RawType$(
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
value);
@ -930,7 +938,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseOr$RawType$Release(
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$Release(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
value);
@ -944,7 +952,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseOr$RawType$Acquire(
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$Acquire(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
value);
@ -959,7 +967,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
long offset = address(bb, indexRO(bb, index));
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(scope(bb), base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue | value)));
@ -971,7 +979,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseAnd$RawType$(
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
value);
@ -985,7 +993,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseAnd$RawType$Release(
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$Release(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
value);
@ -999,7 +1007,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseAnd$RawType$Acquire(
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$Acquire(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
value);
@ -1014,7 +1022,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
long offset = address(bb, indexRO(bb, index));
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(scope(bb), base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue & value)));
@ -1027,7 +1035,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseXor$RawType$(
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
value);
@ -1041,7 +1049,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseXor$RawType$Release(
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$Release(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
value);
@ -1055,7 +1063,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
ByteBufferHandle handle = (ByteBufferHandle)ob;
ByteBuffer bb = (ByteBuffer) Objects.requireNonNull(obb);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseXor$RawType$Acquire(
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$Acquire(scope(bb),
UNSAFE.getReference(bb, BYTE_BUFFER_HB),
address(bb, indexRO(bb, index)),
value);
@ -1070,7 +1078,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
Object base = UNSAFE.getReference(bb, BYTE_BUFFER_HB);
long offset = address(bb, indexRO(bb, index));
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(scope(bb), base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue ^ value)));

View file

@ -24,21 +24,51 @@
*/
package java.lang.invoke;
import jdk.internal.access.foreign.MemoryAddressProxy;
import jdk.internal.access.foreign.MemorySegmentProxy;
import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.vm.annotation.ForceInline;
import java.lang.ref.Reference;
import java.util.Objects;
import static java.lang.invoke.MethodHandleStatics.UNSAFE;
#warn
final class MemoryAccessVarHandle$Type$Helper {
final class MemoryAccessVarHandle$Type$Helper extends MemoryAccessVarHandleBase {
static final boolean BE = UNSAFE.isBigEndian();
static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
static final int VM_ALIGN = $BoxType$.BYTES - 1;
static final VarForm FORM = new VarForm(MemoryAccessVarHandle$Type$Helper.class, MemorySegmentProxy.class, $type$.class, long.class);
MemoryAccessVarHandle$Type$Helper(boolean skipAlignmentMaskCheck, boolean be, long length, long alignmentMask, boolean exact) {
super(FORM, skipAlignmentMaskCheck, be, length, alignmentMask, exact);
}
@Override
final MethodType accessModeTypeUncached(VarHandle.AccessType accessType) {
return accessType.accessModeType(MemorySegmentProxy.class, $type$.class, long.class);
}
@Override
public MemoryAccessVarHandle$Type$Helper withInvokeExactBehavior() {
return hasInvokeExactBehavior() ?
this :
new MemoryAccessVarHandle$Type$Helper(skipAlignmentMaskCheck, be, length, alignmentMask, true);
}
@Override
public MemoryAccessVarHandle$Type$Helper withInvokeBehavior() {
return !hasInvokeExactBehavior() ?
this :
new MemoryAccessVarHandle$Type$Helper(skipAlignmentMaskCheck, be, length, alignmentMask, true);
}
#if[floatingPoint]
@ForceInline
static $rawType$ convEndian(boolean big, $type$ v) {
@ -66,15 +96,15 @@ final class MemoryAccessVarHandle$Type$Helper {
#end[floatingPoint]
@ForceInline
static MemoryAddressProxy checkAddress(Object obb, long offset, long length, boolean ro) {
MemoryAddressProxy oo = (MemoryAddressProxy)Objects.requireNonNull(obb);
static MemorySegmentProxy checkAddress(Object obb, long offset, long length, boolean ro) {
MemorySegmentProxy oo = (MemorySegmentProxy)Objects.requireNonNull(obb);
oo.checkAccess(offset, length, ro);
return oo;
}
@ForceInline
static long offset(MemoryAddressProxy bb, long offset, long alignmentMask) {
long address = offsetNoVMAlignCheck(bb, offset, alignmentMask);
static long offset(boolean skipAlignmentMaskCheck, MemorySegmentProxy bb, long offset, long alignmentMask) {
long address = offsetNoVMAlignCheck(skipAlignmentMaskCheck, bb, offset, alignmentMask);
if ((address & VM_ALIGN) != 0) {
throw MemoryAccessVarHandleBase.newIllegalStateExceptionForMisalignedAccess(address);
}
@ -82,60 +112,66 @@ final class MemoryAccessVarHandle$Type$Helper {
}
@ForceInline
static long offsetNoVMAlignCheck(MemoryAddressProxy bb, long offset, long alignmentMask) {
static long offsetNoVMAlignCheck(boolean skipAlignmentMaskCheck, MemorySegmentProxy bb, long offset, long alignmentMask) {
long base = bb.unsafeGetOffset();
long address = base + offset;
//note: the offset portion has already been aligned-checked, by construction
if ((base & alignmentMask) != 0) {
throw MemoryAccessVarHandleBase.newIllegalStateExceptionForMisalignedAccess(address);
if (skipAlignmentMaskCheck) {
//note: the offset portion has already been aligned-checked, by construction
if ((base & alignmentMask) != 0) {
throw MemoryAccessVarHandleBase.newIllegalStateExceptionForMisalignedAccess(address);
}
} else {
if ((address & alignmentMask) != 0) {
throw MemoryAccessVarHandleBase.newIllegalStateExceptionForMisalignedAccess(address);
}
}
return address;
}
@ForceInline
static $type$ get0(VarHandle ob, Object obb, long base) {
static $type$ get(VarHandle ob, Object obb, long base) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, true);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, true);
#if[floatingPoint]
$rawType$ rawValue = UNSAFE.get$RawType$Unaligned(
$rawType$ rawValue = SCOPED_MEMORY_ACCESS.get$RawType$Unaligned(bb.scope(),
bb.unsafeGetBase(),
offsetNoVMAlignCheck(bb, base, handle.alignmentMask),
offsetNoVMAlignCheck(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
handle.be);
return $Type$.$rawType$BitsTo$Type$(rawValue);
#else[floatingPoint]
#if[byte]
return UNSAFE.get$Type$(
return SCOPED_MEMORY_ACCESS.get$Type$(bb.scope(),
bb.unsafeGetBase(),
offsetNoVMAlignCheck(bb, base, handle.alignmentMask));
offsetNoVMAlignCheck(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask));
#else[byte]
return UNSAFE.get$Type$Unaligned(
return SCOPED_MEMORY_ACCESS.get$Type$Unaligned(bb.scope(),
bb.unsafeGetBase(),
offsetNoVMAlignCheck(bb, base, handle.alignmentMask),
offsetNoVMAlignCheck(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
handle.be);
#end[byte]
#end[floatingPoint]
}
@ForceInline
static void set0(VarHandle ob, Object obb, long base, $type$ value) {
static void set(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
#if[floatingPoint]
UNSAFE.put$RawType$Unaligned(
SCOPED_MEMORY_ACCESS.put$RawType$Unaligned(bb.scope(),
bb.unsafeGetBase(),
offsetNoVMAlignCheck(bb, base, handle.alignmentMask),
offsetNoVMAlignCheck(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
$Type$.$type$ToRaw$RawType$Bits(value),
handle.be);
#else[floatingPoint]
#if[byte]
UNSAFE.put$Type$(
SCOPED_MEMORY_ACCESS.put$Type$(bb.scope(),
bb.unsafeGetBase(),
offsetNoVMAlignCheck(bb, base, handle.alignmentMask),
offsetNoVMAlignCheck(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
#else[byte]
UNSAFE.put$Type$Unaligned(
SCOPED_MEMORY_ACCESS.put$Type$Unaligned(bb.scope(),
bb.unsafeGetBase(),
offsetNoVMAlignCheck(bb, base, handle.alignmentMask),
offsetNoVMAlignCheck(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value,
handle.be);
#end[byte]
@ -143,234 +179,234 @@ final class MemoryAccessVarHandle$Type$Helper {
}
@ForceInline
static $type$ getVolatile0(VarHandle ob, Object obb, long base) {
static $type$ getVolatile(VarHandle ob, Object obb, long base) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, true);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, true);
return convEndian(handle.be,
UNSAFE.get$RawType$Volatile(
SCOPED_MEMORY_ACCESS.get$RawType$Volatile(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask)));
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask)));
}
@ForceInline
static void setVolatile0(VarHandle ob, Object obb, long base, $type$ value) {
static void setVolatile(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
UNSAFE.put$RawType$Volatile(
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
SCOPED_MEMORY_ACCESS.put$RawType$Volatile(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, value));
}
@ForceInline
static $type$ getAcquire0(VarHandle ob, Object obb, long base) {
static $type$ getAcquire(VarHandle ob, Object obb, long base) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, true);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, true);
return convEndian(handle.be,
UNSAFE.get$RawType$Acquire(
SCOPED_MEMORY_ACCESS.get$RawType$Acquire(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask)));
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask)));
}
@ForceInline
static void setRelease0(VarHandle ob, Object obb, long base, $type$ value) {
static void setRelease(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
UNSAFE.put$RawType$Release(
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
SCOPED_MEMORY_ACCESS.put$RawType$Release(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, value));
}
@ForceInline
static $type$ getOpaque0(VarHandle ob, Object obb, long base) {
static $type$ getOpaque(VarHandle ob, Object obb, long base) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, true);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, true);
return convEndian(handle.be,
UNSAFE.get$RawType$Opaque(
SCOPED_MEMORY_ACCESS.get$RawType$Opaque(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask)));
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask)));
}
@ForceInline
static void setOpaque0(VarHandle ob, Object obb, long base, $type$ value) {
static void setOpaque(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
UNSAFE.put$RawType$Opaque(
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
SCOPED_MEMORY_ACCESS.put$RawType$Opaque(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, value));
}
#if[CAS]
@ForceInline
static boolean compareAndSet0(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
static boolean compareAndSet(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
return UNSAFE.compareAndSet$RawType$(
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return SCOPED_MEMORY_ACCESS.compareAndSet$RawType$(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, expected), convEndian(handle.be, value));
}
@ForceInline
static $type$ compareAndExchange0(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
static $type$ compareAndExchange(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return convEndian(handle.be,
UNSAFE.compareAndExchange$RawType$(
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, expected), convEndian(handle.be, value)));
}
@ForceInline
static $type$ compareAndExchangeAcquire0(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
static $type$ compareAndExchangeAcquire(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return convEndian(handle.be,
UNSAFE.compareAndExchange$RawType$Acquire(
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$Acquire(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, expected), convEndian(handle.be, value)));
}
@ForceInline
static $type$ compareAndExchangeRelease0(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
static $type$ compareAndExchangeRelease(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return convEndian(handle.be,
UNSAFE.compareAndExchange$RawType$Release(
SCOPED_MEMORY_ACCESS.compareAndExchange$RawType$Release(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, expected), convEndian(handle.be, value)));
}
@ForceInline
static boolean weakCompareAndSetPlain0(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
static boolean weakCompareAndSetPlain(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
return UNSAFE.weakCompareAndSet$RawType$Plain(
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Plain(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, expected), convEndian(handle.be, value));
}
@ForceInline
static boolean weakCompareAndSet0(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
static boolean weakCompareAndSet(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
return UNSAFE.weakCompareAndSet$RawType$(
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, expected), convEndian(handle.be, value));
}
@ForceInline
static boolean weakCompareAndSetAcquire0(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
static boolean weakCompareAndSetAcquire(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
return UNSAFE.weakCompareAndSet$RawType$Acquire(
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Acquire(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, expected), convEndian(handle.be, value));
}
@ForceInline
static boolean weakCompareAndSetRelease0(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
static boolean weakCompareAndSetRelease(VarHandle ob, Object obb, long base, $type$ expected, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
return UNSAFE.weakCompareAndSet$RawType$Release(
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$Release(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, expected), convEndian(handle.be, value));
}
@ForceInline
static $type$ getAndSet0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndSet(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return convEndian(handle.be,
UNSAFE.getAndSet$RawType$(
SCOPED_MEMORY_ACCESS.getAndSet$RawType$(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, value)));
}
@ForceInline
static $type$ getAndSetAcquire0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndSetAcquire(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return convEndian(handle.be,
UNSAFE.getAndSet$RawType$Acquire(
SCOPED_MEMORY_ACCESS.getAndSet$RawType$Acquire(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, value)));
}
@ForceInline
static $type$ getAndSetRelease0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndSetRelease(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
return convEndian(handle.be,
UNSAFE.getAndSet$RawType$Release(
SCOPED_MEMORY_ACCESS.getAndSet$RawType$Release(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
convEndian(handle.be, value)));
}
#end[CAS]
#if[AtomicAdd]
@ForceInline
static $type$ getAndAdd0(VarHandle ob, Object obb, long base, $type$ delta) {
static $type$ getAndAdd(VarHandle ob, Object obb, long base, $type$ delta) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndAdd$RawType$(
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
delta);
} else {
return getAndAddConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), delta);
return getAndAddConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), delta);
}
}
@ForceInline
static $type$ getAndAddAcquire0(VarHandle ob, Object obb, long base, $type$ delta) {
static $type$ getAndAddAcquire(VarHandle ob, Object obb, long base, $type$ delta) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndAdd$RawType$Acquire(
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$Acquire(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
delta);
} else {
return getAndAddConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), delta);
return getAndAddConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), delta);
}
}
@ForceInline
static $type$ getAndAddRelease0(VarHandle ob, Object obb, long base, $type$ delta) {
static $type$ getAndAddRelease(VarHandle ob, Object obb, long base, $type$ delta) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndAdd$RawType$Release(
return SCOPED_MEMORY_ACCESS.getAndAdd$RawType$Release(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
delta);
} else {
return getAndAddConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), delta);
return getAndAddConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), delta);
}
}
@ForceInline
static $type$ getAndAddConvEndianWithCAS(MemoryAddressProxy bb, long offset, $type$ delta) {
static $type$ getAndAddConvEndianWithCAS(MemorySegmentProxy bb, long offset, $type$ delta) {
$type$ nativeExpectedValue, expectedValue;
Object base = bb.unsafeGetBase();
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(bb.scope(),base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
} while (!SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$(bb.scope(),base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta)));
return expectedValue;
}
@ -378,164 +414,164 @@ final class MemoryAccessVarHandle$Type$Helper {
#if[Bitwise]
@ForceInline
static $type$ getAndBitwiseOr0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndBitwiseOr(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseOr$RawType$(
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
} else {
return getAndBitwiseOrConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value);
return getAndBitwiseOrConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), value);
}
}
@ForceInline
static $type$ getAndBitwiseOrRelease0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndBitwiseOrRelease(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseOr$RawType$Release(
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$Release(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
} else {
return getAndBitwiseOrConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value);
return getAndBitwiseOrConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), value);
}
}
@ForceInline
static $type$ getAndBitwiseOrAcquire0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndBitwiseOrAcquire(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseOr$RawType$Acquire(
return SCOPED_MEMORY_ACCESS.getAndBitwiseOr$RawType$Acquire(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
} else {
return getAndBitwiseOrConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value);
return getAndBitwiseOrConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), value);
}
}
@ForceInline
static $type$ getAndBitwiseOrConvEndianWithCAS(MemoryAddressProxy bb, long offset, $type$ value) {
static $type$ getAndBitwiseOrConvEndianWithCAS(MemorySegmentProxy bb, long offset, $type$ value) {
$type$ nativeExpectedValue, expectedValue;
Object base = bb.unsafeGetBase();
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(bb.scope(),base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
} while (!SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$(bb.scope(),base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue | value)));
return expectedValue;
}
@ForceInline
static $type$ getAndBitwiseAnd0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndBitwiseAnd(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseAnd$RawType$(
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
} else {
return getAndBitwiseAndConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value);
return getAndBitwiseAndConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), value);
}
}
@ForceInline
static $type$ getAndBitwiseAndRelease0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndBitwiseAndRelease(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseAnd$RawType$Release(
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$Release(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
} else {
return getAndBitwiseAndConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value);
return getAndBitwiseAndConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), value);
}
}
@ForceInline
static $type$ getAndBitwiseAndAcquire0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndBitwiseAndAcquire(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseAnd$RawType$Acquire(
return SCOPED_MEMORY_ACCESS.getAndBitwiseAnd$RawType$Acquire(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
} else {
return getAndBitwiseAndConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value);
return getAndBitwiseAndConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), value);
}
}
@ForceInline
static $type$ getAndBitwiseAndConvEndianWithCAS(MemoryAddressProxy bb, long offset, $type$ value) {
static $type$ getAndBitwiseAndConvEndianWithCAS(MemorySegmentProxy bb, long offset, $type$ value) {
$type$ nativeExpectedValue, expectedValue;
Object base = bb.unsafeGetBase();
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(bb.scope(),base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
} while (!SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$(bb.scope(),base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue & value)));
return expectedValue;
}
@ForceInline
static $type$ getAndBitwiseXor0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndBitwiseXor(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseXor$RawType$(
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
} else {
return getAndBitwiseXorConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value);
return getAndBitwiseXorConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), value);
}
}
@ForceInline
static $type$ getAndBitwiseXorRelease0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndBitwiseXorRelease(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseXor$RawType$Release(
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$Release(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
} else {
return getAndBitwiseXorConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value);
return getAndBitwiseXorConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), value);
}
}
@ForceInline
static $type$ getAndBitwiseXorAcquire0(VarHandle ob, Object obb, long base, $type$ value) {
static $type$ getAndBitwiseXorAcquire(VarHandle ob, Object obb, long base, $type$ value) {
MemoryAccessVarHandleBase handle = (MemoryAccessVarHandleBase)ob;
MemoryAddressProxy bb = checkAddress(obb, base, handle.length, false);
MemorySegmentProxy bb = checkAddress(obb, base, handle.length, false);
if (handle.be == BE) {
return UNSAFE.getAndBitwiseXor$RawType$Acquire(
return SCOPED_MEMORY_ACCESS.getAndBitwiseXor$RawType$Acquire(bb.scope(),
bb.unsafeGetBase(),
offset(bb, base, handle.alignmentMask),
offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask),
value);
} else {
return getAndBitwiseXorConvEndianWithCAS(bb, offset(bb, base, handle.alignmentMask), value);
return getAndBitwiseXorConvEndianWithCAS(bb, offset(handle.skipAlignmentMaskCheck, bb, base, handle.alignmentMask), value);
}
}
@ForceInline
static $type$ getAndBitwiseXorConvEndianWithCAS(MemoryAddressProxy bb, long offset, $type$ value) {
static $type$ getAndBitwiseXorConvEndianWithCAS(MemorySegmentProxy bb, long offset, $type$ value) {
$type$ nativeExpectedValue, expectedValue;
Object base = bb.unsafeGetBase();
do {
nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset);
nativeExpectedValue = SCOPED_MEMORY_ACCESS.get$RawType$Volatile(bb.scope(),base, offset);
expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue);
} while (!UNSAFE.weakCompareAndSet$RawType$(base, offset,
} while (!SCOPED_MEMORY_ACCESS.weakCompareAndSet$RawType$(bb.scope(),base, offset,
nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue ^ value)));
return expectedValue;
}

View file

@ -106,7 +106,7 @@ class Bits { // package-private
// These methods should be called whenever direct memory is allocated or
// freed. They allow the user to control the amount of direct memory
// which a process may access. All sizes are specified in bytes.
static void reserveMemory(long size, int cap) {
static void reserveMemory(long size, long cap) {
if (!MEMORY_LIMIT_SET && VM.initLevel() >= 1) {
MAX_MEMORY = VM.maxDirectMemory();
@ -185,7 +185,7 @@ class Bits { // package-private
}
}
private static boolean tryReserveMemory(long size, int cap) {
private static boolean tryReserveMemory(long size, long cap) {
// -XX:MaxDirectMemorySize limits the total capacity rather than the
// actual memory usage, which will differ when buffers are page
@ -203,7 +203,7 @@ class Bits { // package-private
}
static void unreserveMemory(long size, int cap) {
static void unreserveMemory(long size, long cap) {
long cnt = COUNT.decrementAndGet();
long reservedMem = RESERVED_MEMORY.addAndGet(-size);
long totalCap = TOTAL_CAPACITY.addAndGet(-cap);

View file

@ -29,6 +29,7 @@ import jdk.internal.access.JavaNioAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.foreign.MemorySegmentProxy;
import jdk.internal.access.foreign.UnmapperProxy;
import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM.BufferPool;
import jdk.internal.vm.annotation.ForceInline;
@ -193,6 +194,8 @@ public abstract class Buffer {
// Cached unsafe-access object
static final Unsafe UNSAFE = Unsafe.getUnsafe();
static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
/**
* The characteristics of Spliterators that traverse and split elements
* maintained in Buffers.
@ -754,9 +757,18 @@ public abstract class Buffer {
}
@ForceInline
final void checkSegment() {
final ScopedMemoryAccess.Scope scope() {
if (segment != null) {
segment.checkValidState();
return segment.scope();
} else {
return null;
}
}
final void checkScope() {
ScopedMemoryAccess.Scope scope = scope();
if (scope != null) {
scope.checkValidState();
}
}
@ -827,6 +839,21 @@ public abstract class Buffer {
public boolean isLoaded(long address, boolean isSync, long size) {
return MappedMemoryUtils.isLoaded(address, isSync, size);
}
@Override
public void reserveMemory(long size, long cap) {
Bits.reserveMemory(size, cap);
}
@Override
public void unreserveMemory(long size, long cap) {
Bits.unreserveMemory(size, cap);
}
@Override
public int pageSize() {
return Bits.pageSize();
}
});
}

View file

@ -24,6 +24,7 @@
*/
package java.nio;
import jdk.internal.misc.ScopedMemoryAccess;
import jdk.internal.util.ArraysSupport;
/**
@ -31,12 +32,14 @@ import jdk.internal.util.ArraysSupport;
*/
final class BufferMismatch {
final static ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
static int mismatch(ByteBuffer a, int aOff, ByteBuffer b, int bOff, int length) {
int i = 0;
if (length > 7) {
if (a.get(aOff) != b.get(bOff))
return 0;
i = ArraysSupport.vectorizedMismatch(
i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),
a.base(), a.address + aOff,
b.base(), b.address + bOff,
length,
@ -60,7 +63,7 @@ final class BufferMismatch {
&& a.charRegionOrder() != null && b.charRegionOrder() != null) {
if (a.get(aOff) != b.get(bOff))
return 0;
i = ArraysSupport.vectorizedMismatch(
i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
length,
@ -80,7 +83,7 @@ final class BufferMismatch {
if (length > 3 && a.order() == b.order()) {
if (a.get(aOff) != b.get(bOff))
return 0;
i = ArraysSupport.vectorizedMismatch(
i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
length,
@ -100,7 +103,7 @@ final class BufferMismatch {
if (length > 1 && a.order() == b.order()) {
if (a.get(aOff) != b.get(bOff))
return 0;
i = ArraysSupport.vectorizedMismatch(
i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
length,
@ -119,7 +122,7 @@ final class BufferMismatch {
int i = 0;
if (length > 1 && a.order() == b.order()) {
if (Float.floatToRawIntBits(a.get(aOff)) == Float.floatToRawIntBits(b.get(bOff))) {
i = ArraysSupport.vectorizedMismatch(
i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
length,
@ -158,7 +161,7 @@ final class BufferMismatch {
if (length > 0 && a.order() == b.order()) {
if (a.get(aOff) != b.get(bOff))
return 0;
i = ArraysSupport.vectorizedMismatch(
i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
length,
@ -176,7 +179,7 @@ final class BufferMismatch {
int i = 0;
if (length > 0 && a.order() == b.order()) {
if (Double.doubleToRawLongBits(a.get(aOff)) == Double.doubleToRawLongBits(b.get(bOff))) {
i = ArraysSupport.vectorizedMismatch(
i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),
a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
length,

View file

@ -130,22 +130,20 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
}
public $type$ get() {
checkSegment();
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(nextGetIndex()),
$memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(scope(), bb.hb, byteOffset(nextGetIndex()),
{#if[boB]?true:false});
return $fromBits$(x);
}
public $type$ get(int i) {
checkSegment();
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)),
$memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(scope(), bb.hb, byteOffset(checkIndex(i)),
{#if[boB]?true:false});
return $fromBits$(x);
}
#if[streamableType]
$type$ getUnchecked(int i) {
$memtype$ x = UNSAFE.get$Memtype$Unaligned(bb.hb, byteOffset(i),
$memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(null, bb.hb, byteOffset(i),
{#if[boB]?true:false});
return $fromBits$(x);
}
@ -155,9 +153,8 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
public $Type$Buffer put($type$ x) {
#if[rw]
checkSegment();
$memtype$ y = $toBits$(x);
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(nextPutIndex()), y,
SCOPED_MEMORY_ACCESS.put$Memtype$Unaligned(scope(), bb.hb, byteOffset(nextPutIndex()), y,
{#if[boB]?true:false});
return this;
#else[rw]
@ -167,9 +164,8 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
public $Type$Buffer put(int i, $type$ x) {
#if[rw]
checkSegment();
$memtype$ y = $toBits$(x);
UNSAFE.put$Memtype$Unaligned(bb.hb, byteOffset(checkIndex(i)), y,
SCOPED_MEMORY_ACCESS.put$Memtype$Unaligned(scope(), bb.hb, byteOffset(checkIndex(i)), y,
{#if[boB]?true:false});
return this;
#else[rw]

View file

@ -33,8 +33,7 @@ class XXX {
private $type$ get$Type$(long a) {
try {
checkSegment();
$memtype$ x = UNSAFE.get$Memtype$Unaligned(null, a, bigEndian);
$memtype$ x = SCOPED_MEMORY_ACCESS.get$Memtype$Unaligned(scope(), null, a, bigEndian);
return $fromBits$(x);
} finally {
Reference.reachabilityFence(this);
@ -62,9 +61,8 @@ class XXX {
private ByteBuffer put$Type$(long a, $type$ x) {
#if[rw]
try {
checkSegment();
$memtype$ y = $toBits$(x);
UNSAFE.put$Memtype$Unaligned(null, a, y, bigEndian);
SCOPED_MEMORY_ACCESS.put$Memtype$Unaligned(scope(), null, a, y, bigEndian);
} finally {
Reference.reachabilityFence(this);
}

View file

@ -31,6 +31,7 @@ import java.io.FileDescriptor;
import java.lang.ref.Reference;
import java.util.Objects;
import jdk.internal.access.foreign.MemorySegmentProxy;
import jdk.internal.misc.ScopedMemoryAccess.Scope;
import jdk.internal.misc.VM;
import jdk.internal.ref.Cleaner;
import sun.nio.ch.DirectBuffer;
@ -264,6 +265,17 @@ class Direct$Type$Buffer$RW$$BO$
#if[rw]
public long address() {
Scope scope = scope();
if (scope != null) {
if (scope.ownerThread() == null) {
throw new UnsupportedOperationException("ByteBuffer derived from shared segments not supported");
}
try {
scope.checkValidState();
} catch (Scope.ScopedAccessError e) {
throw new IllegalStateException("This segment is already closed");
}
}
return address;
}
@ -273,8 +285,7 @@ class Direct$Type$Buffer$RW$$BO$
public $type$ get() {
try {
checkSegment();
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(nextGetIndex()))));
return $fromBits$($swap$(SCOPED_MEMORY_ACCESS.get$Swaptype$(scope(), null, ix(nextGetIndex()))));
} finally {
Reference.reachabilityFence(this);
}
@ -282,8 +293,7 @@ class Direct$Type$Buffer$RW$$BO$
public $type$ get(int i) {
try {
checkSegment();
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(checkIndex(i)))));
return $fromBits$($swap$(SCOPED_MEMORY_ACCESS.get$Swaptype$(scope(), null, ix(checkIndex(i)))));
} finally {
Reference.reachabilityFence(this);
}
@ -292,7 +302,7 @@ class Direct$Type$Buffer$RW$$BO$
#if[streamableType]
$type$ getUnchecked(int i) {
try {
return $fromBits$($swap$(UNSAFE.get$Swaptype$(ix(i))));
return $fromBits$($swap$(SCOPED_MEMORY_ACCESS.get$Swaptype$(null, null, ix(i))));
} finally {
Reference.reachabilityFence(this);
}
@ -301,7 +311,6 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer get($type$[] dst, int offset, int length) {
#if[rw]
checkSegment();
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
Objects.checkFromIndexSize(offset, length, dst.length);
int pos = position();
@ -315,7 +324,7 @@ class Direct$Type$Buffer$RW$$BO$
try {
#if[!byte]
if (order() != ByteOrder.nativeOrder())
UNSAFE.copySwapMemory(null,
SCOPED_MEMORY_ACCESS.copySwapMemory(scope(), null, null,
ix(pos),
dst,
dstOffset,
@ -323,7 +332,7 @@ class Direct$Type$Buffer$RW$$BO$
(long)1 << $LG_BYTES_PER_VALUE$);
else
#end[!byte]
UNSAFE.copyMemory(null,
SCOPED_MEMORY_ACCESS.copyMemory(scope(), null, null,
ix(pos),
dst,
dstOffset,
@ -343,7 +352,6 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
#if[rw]
checkSegment();
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
Objects.checkFromIndexSize(index, length, limit());
Objects.checkFromIndexSize(offset, length, dst.length);
@ -352,7 +360,7 @@ class Direct$Type$Buffer$RW$$BO$
try {
#if[!byte]
if (order() != ByteOrder.nativeOrder())
UNSAFE.copySwapMemory(null,
SCOPED_MEMORY_ACCESS.copySwapMemory(scope(), null, null,
ix(index),
dst,
dstOffset,
@ -360,7 +368,7 @@ class Direct$Type$Buffer$RW$$BO$
(long)1 << $LG_BYTES_PER_VALUE$);
else
#end[!byte]
UNSAFE.copyMemory(null,
SCOPED_MEMORY_ACCESS.copyMemory(scope(), null, null,
ix(index),
dst,
dstOffset,
@ -381,8 +389,7 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer put($type$ x) {
#if[rw]
try {
checkSegment();
UNSAFE.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
SCOPED_MEMORY_ACCESS.put$Swaptype$(scope(), null, ix(nextPutIndex()), $swap$($toBits$(x)));
} finally {
Reference.reachabilityFence(this);
}
@ -395,8 +402,7 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer put(int i, $type$ x) {
#if[rw]
try {
checkSegment();
UNSAFE.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
SCOPED_MEMORY_ACCESS.put$Swaptype$(scope(), null, ix(checkIndex(i)), $swap$($toBits$(x)));
} finally {
Reference.reachabilityFence(this);
}
@ -408,7 +414,6 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer put($Type$Buffer src) {
#if[rw]
checkSegment();
super.put(src);
return this;
#else[rw]
@ -418,7 +423,6 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer put(int index, $Type$Buffer src, int offset, int length) {
#if[rw]
checkSegment();
super.put(index, src, offset, length);
return this;
#else[rw]
@ -428,7 +432,6 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer put($type$[] src, int offset, int length) {
#if[rw]
checkSegment();
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
Objects.checkFromIndexSize(offset, length, src.length);
int pos = position();
@ -442,7 +445,7 @@ class Direct$Type$Buffer$RW$$BO$
try {
#if[!byte]
if (order() != ByteOrder.nativeOrder())
UNSAFE.copySwapMemory(src,
SCOPED_MEMORY_ACCESS.copySwapMemory(scope(), null, src,
srcOffset,
null,
ix(pos),
@ -450,7 +453,7 @@ class Direct$Type$Buffer$RW$$BO$
(long)1 << $LG_BYTES_PER_VALUE$);
else
#end[!byte]
UNSAFE.copyMemory(src,
SCOPED_MEMORY_ACCESS.copyMemory(scope(), null, src,
srcOffset,
null,
ix(pos),
@ -470,7 +473,6 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer put(int index, $type$[] src, int offset, int length) {
#if[rw]
checkSegment();
if (((long)length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
Objects.checkFromIndexSize(index, length, limit());
Objects.checkFromIndexSize(offset, length, src.length);
@ -480,7 +482,7 @@ class Direct$Type$Buffer$RW$$BO$
try {
#if[!byte]
if (order() != ByteOrder.nativeOrder())
UNSAFE.copySwapMemory(src,
SCOPED_MEMORY_ACCESS.copySwapMemory(scope(), null, src,
srcOffset,
null,
ix(index),
@ -488,11 +490,9 @@ class Direct$Type$Buffer$RW$$BO$
(long)1 << $LG_BYTES_PER_VALUE$);
else
#end[!byte]
UNSAFE.copyMemory(src,
srcOffset,
null,
ix(index),
(long)length << $LG_BYTES_PER_VALUE$);
SCOPED_MEMORY_ACCESS.copyMemory(
scope(), null, src,
srcOffset, null, ix(index), (long)length << $LG_BYTES_PER_VALUE$);
} finally {
Reference.reachabilityFence(this);
}
@ -512,7 +512,8 @@ class Direct$Type$Buffer$RW$$BO$
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
try {
UNSAFE.copyMemory(ix(pos), ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
SCOPED_MEMORY_ACCESS.copyMemory(scope(), null, null,
ix(pos), null, ix(0), (long)rem << $LG_BYTES_PER_VALUE$);
} finally {
Reference.reachabilityFence(this);
}

View file

@ -162,12 +162,10 @@ class Heap$Type$Buffer$RW$
#end[byte]
public $type$ get() {
checkSegment();
return hb[ix(nextGetIndex())];
}
public $type$ get(int i) {
checkSegment();
return hb[ix(checkIndex(i))];
}
@ -178,7 +176,7 @@ class Heap$Type$Buffer$RW$
#end[streamableType]
public $Type$Buffer get($type$[] dst, int offset, int length) {
checkSegment();
checkScope();
Objects.checkFromIndexSize(offset, length, dst.length);
int pos = position();
if (length > limit() - pos)
@ -189,7 +187,7 @@ class Heap$Type$Buffer$RW$
}
public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
checkSegment();
checkScope();
Objects.checkFromIndexSize(index, length, limit());
Objects.checkFromIndexSize(offset, length, dst.length);
System.arraycopy(hb, ix(index), dst, offset, length);
@ -208,7 +206,6 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer put($type$ x) {
#if[rw]
checkSegment();
hb[ix(nextPutIndex())] = x;
return this;
#else[rw]
@ -218,7 +215,6 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer put(int i, $type$ x) {
#if[rw]
checkSegment();
hb[ix(checkIndex(i))] = x;
return this;
#else[rw]
@ -228,7 +224,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer put($type$[] src, int offset, int length) {
#if[rw]
checkSegment();
checkScope();
Objects.checkFromIndexSize(offset, length, src.length);
int pos = position();
if (length > limit() - pos)
@ -243,7 +239,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer put($Type$Buffer src) {
#if[rw]
checkSegment();
checkScope();
super.put(src);
return this;
#else[rw]
@ -253,7 +249,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer put(int index, $Type$Buffer src, int offset, int length) {
#if[rw]
checkSegment();
checkScope();
super.put(index, src, offset, length);
return this;
#else[rw]
@ -263,7 +259,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer put(int index, $type$[] src, int offset, int length) {
#if[rw]
checkSegment();
checkScope();
Objects.checkFromIndexSize(index, length, limit());
Objects.checkFromIndexSize(offset, length, src.length);
System.arraycopy(src, offset, hb, ix(index), length);
@ -276,7 +272,7 @@ class Heap$Type$Buffer$RW$
#if[char]
public $Type$Buffer put(String src, int start, int end) {
checkSegment();
checkScope();
int length = end - start;
Objects.checkFromIndexSize(start, length, src.length());
if (isReadOnly())
@ -328,20 +324,18 @@ class Heap$Type$Buffer$RW$
#if[rw]
public char getChar() {
checkSegment();
return UNSAFE.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
return SCOPED_MEMORY_ACCESS.getCharUnaligned(scope(), hb, byteOffset(nextGetIndex(2)), bigEndian);
}
public char getChar(int i) {
return UNSAFE.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
return SCOPED_MEMORY_ACCESS.getCharUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), bigEndian);
}
#end[rw]
public $Type$Buffer putChar(char x) {
#if[rw]
checkSegment();
UNSAFE.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
SCOPED_MEMORY_ACCESS.putCharUnaligned(scope(), hb, byteOffset(nextPutIndex(2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -350,8 +344,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putChar(int i, char x) {
#if[rw]
checkSegment();
UNSAFE.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
SCOPED_MEMORY_ACCESS.putCharUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -383,21 +376,18 @@ class Heap$Type$Buffer$RW$
#if[rw]
public short getShort() {
checkSegment();
return UNSAFE.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
return SCOPED_MEMORY_ACCESS.getShortUnaligned(scope(), hb, byteOffset(nextGetIndex(2)), bigEndian);
}
public short getShort(int i) {
checkSegment();
return UNSAFE.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
return SCOPED_MEMORY_ACCESS.getShortUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), bigEndian);
}
#end[rw]
public $Type$Buffer putShort(short x) {
#if[rw]
checkSegment();
UNSAFE.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
SCOPED_MEMORY_ACCESS.putShortUnaligned(scope(), hb, byteOffset(nextPutIndex(2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -406,8 +396,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putShort(int i, short x) {
#if[rw]
checkSegment();
UNSAFE.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
SCOPED_MEMORY_ACCESS.putShortUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -439,21 +428,18 @@ class Heap$Type$Buffer$RW$
#if[rw]
public int getInt() {
checkSegment();
return UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
return SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(nextGetIndex(4)), bigEndian);
}
public int getInt(int i) {
checkSegment();
return UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
return SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), bigEndian);
}
#end[rw]
public $Type$Buffer putInt(int x) {
#if[rw]
checkSegment();
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian);
SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(nextPutIndex(4)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -462,8 +448,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putInt(int i, int x) {
#if[rw]
checkSegment();
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -495,21 +480,18 @@ class Heap$Type$Buffer$RW$
#if[rw]
public long getLong() {
checkSegment();
return UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
return SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(nextGetIndex(8)), bigEndian);
}
public long getLong(int i) {
checkSegment();
return UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
return SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), bigEndian);
}
#end[rw]
public $Type$Buffer putLong(long x) {
#if[rw]
checkSegment();
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian);
SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(nextPutIndex(8)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -518,8 +500,7 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putLong(int i, long x) {
#if[rw]
checkSegment();
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -551,14 +532,12 @@ class Heap$Type$Buffer$RW$
#if[rw]
public float getFloat() {
checkSegment();
int x = UNSAFE.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
int x = SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(nextGetIndex(4)), bigEndian);
return Float.intBitsToFloat(x);
}
public float getFloat(int i) {
checkSegment();
int x = UNSAFE.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
int x = SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), bigEndian);
return Float.intBitsToFloat(x);
}
@ -566,9 +545,8 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putFloat(float x) {
#if[rw]
checkSegment();
int y = Float.floatToRawIntBits(x);
UNSAFE.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian);
SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(nextPutIndex(4)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -577,9 +555,8 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putFloat(int i, float x) {
#if[rw]
checkSegment();
int y = Float.floatToRawIntBits(x);
UNSAFE.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -611,14 +588,12 @@ class Heap$Type$Buffer$RW$
#if[rw]
public double getDouble() {
checkSegment();
long x = UNSAFE.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
long x = SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(nextGetIndex(8)), bigEndian);
return Double.longBitsToDouble(x);
}
public double getDouble(int i) {
checkSegment();
long x = UNSAFE.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
long x = SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), bigEndian);
return Double.longBitsToDouble(x);
}
@ -626,9 +601,8 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putDouble(double x) {
#if[rw]
checkSegment();
long y = Double.doubleToRawLongBits(x);
UNSAFE.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian);
SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(nextPutIndex(8)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@ -637,9 +611,8 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer putDouble(int i, double x) {
#if[rw]
checkSegment();
long y = Double.doubleToRawLongBits(x);
UNSAFE.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();

View file

@ -31,6 +31,7 @@ import java.util.Objects;
import jdk.internal.access.foreign.MemorySegmentProxy;
import jdk.internal.access.foreign.UnmapperProxy;
import jdk.internal.misc.ScopedMemoryAccess;
/**
@ -87,6 +88,8 @@ public abstract class MappedByteBuffer
// determines the behavior of force operations.
private final boolean isSync;
static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
// This should only be invoked by the DirectByteBuffer constructors
//
MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
@ -173,7 +176,7 @@ public abstract class MappedByteBuffer
if (fd == null) {
return true;
}
return MappedMemoryUtils.isLoaded(address, isSync, capacity());
return SCOPED_MEMORY_ACCESS.isLoaded(scope(), address, isSync, capacity());
}
/**
@ -191,7 +194,7 @@ public abstract class MappedByteBuffer
return this;
}
try {
MappedMemoryUtils.load(address, isSync, capacity());
SCOPED_MEMORY_ACCESS.load(scope(), address, isSync, capacity());
} finally {
Reference.reachabilityFence(this);
}
@ -280,7 +283,7 @@ public abstract class MappedByteBuffer
if ((address != 0) && (limit != 0)) {
// check inputs
Objects.checkFromIndexSize(index, length, limit);
MappedMemoryUtils.force(fd, address, isSync, index, length);
SCOPED_MEMORY_ACCESS.force(scope(), fd, address, isSync, index, length);
}
return this;
}

View file

@ -1045,11 +1045,9 @@ public abstract class $Type$Buffer
if (this.order() == src.order()) {
#end[!byte]
try {
UNSAFE.copyMemory(srcBase,
srcAddr,
base,
addr,
len);
SCOPED_MEMORY_ACCESS.copyMemory(
scope(), src.scope(), srcBase,
srcAddr, base, addr, len);
} finally {
Reference.reachabilityFence(src);
Reference.reachabilityFence(this);
@ -1057,12 +1055,9 @@ public abstract class $Type$Buffer
#if[!byte]
} else {
try {
UNSAFE.copySwapMemory(srcBase,
srcAddr,
base,
addr,
len,
(long)1 << $LG_BYTES_PER_VALUE$);
SCOPED_MEMORY_ACCESS.copySwapMemory(
scope(), src.scope(), srcBase,
srcAddr, base, addr, len, (long)1 << $LG_BYTES_PER_VALUE$);
} finally {
Reference.reachabilityFence(src);
Reference.reachabilityFence(this);