From: <sp...@us...> - 2011-07-12 19:29:22
|
Revision: 3577 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3577&view=rev Author: spasi Date: 2011-07-12 19:29:15 +0000 (Tue, 12 Jul 2011) Log Message: ----------- Added friendly error message when a non-static inner class is registered with the transformer. Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedForeach.java trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedForeach.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedForeach.java 2011-07-12 18:30:56 UTC (rev 3576) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedForeach.java 2011-07-12 19:29:15 UTC (rev 3577) @@ -40,8 +40,8 @@ */ public class MappedForeach<T extends MappedObject> implements Iterable<T> { - private final T mapped; - private final int elementCount; + final T mapped; + final int elementCount; MappedForeach(T mapped, int elementCount) { this.mapped = mapped; Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java 2011-07-12 18:30:56 UTC (rev 3576) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java 2011-07-12 19:29:15 UTC (rev 3577) @@ -36,7 +36,7 @@ static final boolean PRINT_ACTIVITY = false;//LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintActivity"); static final boolean PRINT_BYTECODE = false; //LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintBytecode"); - private static final Map<String, MappedSubtypeInfo> className_to_subtype; + static final Map<String, MappedSubtypeInfo> className_to_subtype; static { className_to_subtype = new HashMap<String, MappedSubtypeInfo>(); @@ -80,6 +80,9 @@ if ( mapped == null ) throw new InternalError("missing " + MappedType.class.getName() + " annotation"); + if ( type.getEnclosingClass() != null && !Modifier.isStatic(type.getModifiers()) ) + throw new InternalError("only top-level or static inner classes are allowed"); + String className = jvmClassName(type); MappedSubtypeInfo mappedType = new MappedSubtypeInfo(className, mapped.sizeof(), mapped.align()); @@ -88,7 +91,7 @@ for ( Field field : type.getDeclaredFields() ) { // static fields are never mapped - if ( (field.getModifiers() & Modifier.STATIC) != 0 ) + if ( Modifier.isStatic(field.getModifiers()) ) continue; // we only support primitives and ByteBuffers @@ -135,7 +138,7 @@ } } - private static final String view_constructor_method = "_construct_view_"; + static final String view_constructor_method = "_construct_view_"; static byte[] transformFieldAccess(final String className, byte[] bytecode) { int flags = 0;//ClassWriter.COMPUTE_FRAMES; @@ -525,7 +528,7 @@ } } - private static void pushInt(MethodVisitor mv, int value) { + static void pushInt(MethodVisitor mv, int value) { if ( value == -1 ) mv.visitInsn(ICONST_M1); else if ( value == 0 ) @@ -548,7 +551,7 @@ mv.visitLdcInsn(Integer.valueOf(value)); } - private static String jvmClassName(Class<?> type) { + static String jvmClassName(Class<?> type) { return type.getName().replace('.', '/'); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sp...@us...> - 2011-07-12 20:40:11
|
Revision: 3578 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3578&view=rev Author: spasi Date: 2011-07-12 20:40:05 +0000 (Tue, 12 Jul 2011) Log Message: ----------- Added bounds check to copyRange. Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java 2011-07-12 19:29:15 UTC (rev 3577) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java 2011-07-12 20:40:05 UTC (rev 3578) @@ -106,6 +106,11 @@ } public static void copy(MappedObject src, MappedObject dst, int bytes) { + if ( MappedObject.CHECKS ) { + src.checkRange(bytes); + dst.checkRange(bytes); + } + MappedObjectUnsafe.INSTANCE.copyMemory(src.viewAddress, dst.viewAddress, bytes); } Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java 2011-07-12 19:29:15 UTC (rev 3577) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java 2011-07-12 20:40:05 UTC (rev 3578) @@ -33,6 +33,7 @@ import org.lwjgl.LWJGLUtil; +import java.nio.BufferOverflowException; import java.nio.ByteBuffer; /** @@ -97,10 +98,19 @@ } final void checkAddress(final long address) { - if ( preventGC.capacity() < (address - MappedObjectUnsafe.getBufferBaseAddress(preventGC) + stride) ) + final long base = MappedObjectUnsafe.getBufferBaseAddress(preventGC); + if ( address < base || preventGC.capacity() < (address - base + stride) ) throw new IndexOutOfBoundsException(); } + final void checkRange(final int bytes) { + if ( bytes < 0 ) + throw new IllegalArgumentException(); + + if ( preventGC.capacity() < (viewAddress - MappedObjectUnsafe.getBufferBaseAddress(preventGC) + bytes) ) + throw new BufferOverflowException(); + } + /** * Creates a MappedObject instance, mapping the memory region of the specified direct ByteBuffer. * <p/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sp...@us...> - 2011-07-12 21:30:55
|
Revision: 3581 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3581&view=rev Author: spasi Date: 2011-07-12 21:30:48 +0000 (Tue, 12 Jul 2011) Log Message: ----------- Fixed stackmap and classloading bugs. Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java 2011-07-12 20:59:27 UTC (rev 3580) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java 2011-07-12 21:30:48 UTC (rev 3581) @@ -51,7 +51,7 @@ */ public class MappedObject { - static final boolean CHECKS = false;//LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.Checks"); + static final boolean CHECKS = LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.Checks"); public MappedObject() { // Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java 2011-07-12 20:59:27 UTC (rev 3580) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java 2011-07-12 21:30:48 UTC (rev 3581) @@ -8,13 +8,13 @@ import org.objectweb.asm.*; import org.objectweb.asm.util.TraceClassVisitor; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.*; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; +import java.util.StringTokenizer; import static org.objectweb.asm.Opcodes.*; @@ -32,8 +32,8 @@ */ public class MappedObjectTransformer { - static final boolean PRINT_TIMING = false;//LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintTiming"); - static final boolean PRINT_ACTIVITY = false;//LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintActivity"); + static final boolean PRINT_TIMING = LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintTiming"); + static final boolean PRINT_ACTIVITY = LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintActivity"); static final boolean PRINT_BYTECODE = false; //LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintBytecode"); static final Map<String, MappedSubtypeInfo> className_to_subtype; @@ -138,13 +138,24 @@ } } - static final String view_constructor_method = "_construct_view_"; + static boolean is_currently_computing_frames = false; + static final String view_constructor_method = "_construct_view_"; static byte[] transformFieldAccess(final String className, byte[] bytecode) { - int flags = 0;//ClassWriter.COMPUTE_FRAMES; + int flags = ClassWriter.COMPUTE_FRAMES; - ClassWriter writer = new ClassWriter(flags); + ClassWriter writer = new ClassWriter(flags) { + // HACK: prevent user-code static-initialization-blocks to be executed + @Override + protected String getCommonSuperClass(String a, String b) { + if ( is_currently_computing_frames ) + if ( !a.startsWith("java/") || !b.startsWith("java/") ) + return "java/lang/Object"; + return super.getCommonSuperClass(a, b); + } + }; + ClassAdapter adapter = new ClassAdapter(writer) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { @@ -192,14 +203,14 @@ bytecode = writer.toByteArray(); if ( PRINT_BYTECODE ) - printBytecode(bytecode, adapter); + printBytecode(bytecode); return bytecode; } - private static void printBytecode(byte[] bytecode, ClassAdapter adapter) { + private static void printBytecode(byte[] bytecode) { StringWriter sw = new StringWriter(); - ClassVisitor tracer = new TraceClassVisitor(adapter, new PrintWriter(sw)); + ClassVisitor tracer = new TraceClassVisitor(new ClassWriter(0), new PrintWriter(sw)); new ClassReader(bytecode).accept(tracer, 0); String dump = sw.toString(); @@ -227,13 +238,16 @@ super.visitTypeInsn(opcode, typeName); } - - private int requireExtraStack = 0; - + @Override - public void visitMaxs(int maxStack, int maxLocals) - { - super.visitMaxs(maxStack+this.requireExtraStack, maxLocals); + public void visitMaxs(int a, int b) { + try { + is_currently_computing_frames = true; + + super.visitMaxs(a, b); + } finally { + is_currently_computing_frames = false; + } } @Override @@ -252,7 +266,7 @@ if ( (isMapDirectMethod || isMapBufferMethod) || isMallocMethod ) { if ( isMallocMethod ) { - // stack: count + // stack: count pushInt(super.mv, mappedType.sizeof); // stack: sizeof, count super.visitInsn(IMUL); @@ -282,7 +296,6 @@ // stack: int, int, buffer, new, new super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "setup", "(L" + jvmClassName(MappedObject.class) + ";Ljava/nio/ByteBuffer;II)V"); // stack: new - this.requireExtraStack = 5; return; } @@ -296,7 +309,6 @@ // stack: new, this super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "dup", "(L" + jvmClassName(MappedObject.class) + ";L" + jvmClassName(MappedObject.class) + ";)L" + jvmClassName(MappedObject.class) + ";"); // stack: new - this.requireExtraStack = 3; return; } @@ -310,7 +322,6 @@ // stack: new, this super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "slice", "(L" + jvmClassName(MappedObject.class) + ";L" + jvmClassName(MappedObject.class) + ";)L" + jvmClassName(MappedObject.class) + ";"); // stack: new - this.requireExtraStack = 3; return; } @@ -322,7 +333,6 @@ // stack: this, this super.visitMethodInsn(INVOKEVIRTUAL, className, view_constructor_method, "()V"); // stack: this - this.requireExtraStack = 2; return; } @@ -334,7 +344,6 @@ // stack: sizeof, target, this super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "copy", "(L" + jvmClassName(MappedObject.class) + ";L" + jvmClassName(MappedObject.class) + ";I)V"); // stack: - - this.requireExtraStack = 3; return; } @@ -346,7 +355,6 @@ // stack: bytes, target, this super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "copy", "(L" + jvmClassName(MappedObject.class) + ";L" + jvmClassName(MappedObject.class) + ";I)V"); // stack: - - this.requireExtraStack = 4; return; } } @@ -488,13 +496,12 @@ // stack: int, long super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "newBuffer", "(JI)L" + jvmClassName(ByteBuffer.class) + ";"); // stack: buffer - this.requireExtraStack = 4; return; } } if ( opcode == PUTFIELD ) { - // stack: value, ref + // stack: value, ref super.visitInsn(SWAP); // stack: ref, value super.visitFieldInsn(GETFIELD, mappedSubtype.className, "viewAddress", "J"); @@ -505,11 +512,10 @@ // stack: long, value super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), typeName.toLowerCase() + "put", "(" + typeName + "J)V"); // stack - - this.requireExtraStack = 4+(int)(mappedSubtype.fieldToLength.get(fieldName).longValue()>>2); return; } if ( opcode == GETFIELD ) { - // stack: ref + // stack: ref super.visitFieldInsn(GETFIELD, mappedSubtype.className, "viewAddress", "J"); // stack: long super.visitLdcInsn(fieldOffset); @@ -518,7 +524,6 @@ // stack: long super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), typeName.toLowerCase() + "get", "(J)" + typeName); // stack: value - this.requireExtraStack = 4; return; } @@ -576,4 +581,59 @@ } } + public static String exportConfiguration() { + StringBuilder sb = new StringBuilder(); + + for ( MappedSubtypeInfo info : className_to_subtype.values() ) { + sb.append("class\t" + info.className + "\t" + info.sizeof + "\t" + info.align + "\r\n"); + + for ( String fieldName : info.fieldToOffset.keySet() ) { + sb.append("field\t" + info.className + "\t" + fieldName + "\t" + info.fieldToOffset.get(fieldName) + "\t" + info.fieldToLength.get(fieldName) + "\r\n"); + } + } + + className_to_subtype.clear(); + + return sb.toString(); + } + + public static void importConfigation(String input) { + className_to_subtype.clear(); + + try { + BufferedReader br = new BufferedReader(new StringReader(input)); + + while ( true ) { + String line = br.readLine(); + if ( line == null ) + break; + if ( (line = line.trim()).isEmpty() ) + continue; + + StringTokenizer st = new StringTokenizer(line, "\t"); + + String type = st.nextToken(); + if ( type.equals("class") ) { + String className = st.nextToken(); + int sizeof = Integer.parseInt(st.nextToken()); + int align = Integer.parseInt(st.nextToken()); + + className_to_subtype.put(className, new MappedSubtypeInfo(className, sizeof, align)); + } else if ( type.equals("field") ) { + MappedObjectTransformer.MappedSubtypeInfo info = className_to_subtype.get(st.nextToken()); + String methodName = st.nextToken(); + int off = Integer.parseInt(st.nextToken()); + int len = Integer.parseInt(st.nextToken()); + + info.fieldToOffset.put(methodName, Long.valueOf(off)); + info.fieldToLength.put(methodName, Long.valueOf(len)); + } else { + throw new IllegalStateException(type); + } + } + } catch (IOException exc) { + throw new IllegalStateException("never happens"); + } + } + } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sp...@us...> - 2011-07-13 12:44:31
|
Revision: 3583 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3583&view=rev Author: spasi Date: 2011-07-13 12:44:25 +0000 (Wed, 13 Jul 2011) Log Message: ----------- Made MappedForeach package private (foreach returns Iterable now) and changed next() to go through the bounds check. Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedForeach.java trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedForeach.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedForeach.java 2011-07-12 22:07:32 UTC (rev 3582) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedForeach.java 2011-07-13 12:44:25 UTC (rev 3583) @@ -38,7 +38,7 @@ * * @author Riven */ -public class MappedForeach<T extends MappedObject> implements Iterable<T> { +final class MappedForeach<T extends MappedObject> implements Iterable<T> { final T mapped; final int elementCount; @@ -58,8 +58,7 @@ } public T next() { - mapped.viewAddress = mapped.baseAddress + (this.index++) * mapped.stride; - + MappedHelper.put_view(mapped, this.index++); return mapped; } Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java 2011-07-12 22:07:32 UTC (rev 3582) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java 2011-07-13 12:44:25 UTC (rev 3583) @@ -214,7 +214,7 @@ * For convenience you are encouraged to static-import this specific method: * <code>import static org.lwjgl.util.mapped.MappedObject.foreach;</code> */ - public static <T extends MappedObject> MappedForeach<T> foreach(T mapped, int elementCount) { + public static <T extends MappedObject> Iterable<T> foreach(T mapped, int elementCount) { return new MappedForeach<T>(mapped, elementCount); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sp...@us...> - 2011-07-23 22:29:03
|
Revision: 3600 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3600&view=rev Author: spasi Date: 2011-07-23 22:28:57 +0000 (Sat, 23 Jul 2011) Log Message: ----------- Added support for volatile keyword. Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java 2011-07-23 22:02:01 UTC (rev 3599) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java 2011-07-23 22:28:57 UTC (rev 3600) @@ -149,6 +149,22 @@ return MappedObjectUnsafe.INSTANCE.getByte(mapped.viewAddress + fieldOffset); } + public static void bvput(byte value, long addr) { + MappedObjectUnsafe.INSTANCE.putByteVolatile(null, addr, value); + } + + public static void bvput(MappedObject mapped, byte value, int fieldOffset) { + MappedObjectUnsafe.INSTANCE.putByteVolatile(null, mapped.viewAddress + fieldOffset, value); + } + + public static byte bvget(long addr) { + return MappedObjectUnsafe.INSTANCE.getByteVolatile(null, addr); + } + + public static byte bvget(MappedObject mapped, int fieldOffset) { + return MappedObjectUnsafe.INSTANCE.getByteVolatile(null, mapped.viewAddress + fieldOffset); + } + // short public static void sput(short value, long addr) { @@ -167,6 +183,22 @@ return MappedObjectUnsafe.INSTANCE.getShort(mapped.viewAddress + fieldOffset); } + public static void svput(short value, long addr) { + MappedObjectUnsafe.INSTANCE.putShortVolatile(null, addr, value); + } + + public static void svput(MappedObject mapped, short value, int fieldOffset) { + MappedObjectUnsafe.INSTANCE.putShortVolatile(null, mapped.viewAddress + fieldOffset, value); + } + + public static short svget(long addr) { + return MappedObjectUnsafe.INSTANCE.getShortVolatile(null, addr); + } + + public static short svget(MappedObject mapped, int fieldOffset) { + return MappedObjectUnsafe.INSTANCE.getShortVolatile(null, mapped.viewAddress + fieldOffset); + } + // char public static void cput(char value, long addr) { @@ -185,6 +217,22 @@ return MappedObjectUnsafe.INSTANCE.getChar(mapped.viewAddress + fieldOffset); } + public static void cvput(char value, long addr) { + MappedObjectUnsafe.INSTANCE.putCharVolatile(null, addr, value); + } + + public static void cvput(MappedObject mapped, char value, int fieldOffset) { + MappedObjectUnsafe.INSTANCE.putCharVolatile(null, mapped.viewAddress + fieldOffset, value); + } + + public static char cvget(long addr) { + return MappedObjectUnsafe.INSTANCE.getCharVolatile(null, addr); + } + + public static char cvget(MappedObject mapped, int fieldOffset) { + return MappedObjectUnsafe.INSTANCE.getCharVolatile(null, mapped.viewAddress + fieldOffset); + } + // int public static void iput(int value, long addr) { @@ -203,6 +251,22 @@ return MappedObjectUnsafe.INSTANCE.getInt(mapped.viewAddress + fieldOffset); } + public static void ivput(int value, long addr) { + MappedObjectUnsafe.INSTANCE.putIntVolatile(null, addr, value); + } + + public static void ivput(MappedObject mapped, int value, int fieldOffset) { + MappedObjectUnsafe.INSTANCE.putIntVolatile(null, mapped.viewAddress + fieldOffset, value); + } + + public static int ivget(long address) { + return MappedObjectUnsafe.INSTANCE.getIntVolatile(null, address); + } + + public static int ivget(MappedObject mapped, int fieldOffset) { + return MappedObjectUnsafe.INSTANCE.getIntVolatile(null, mapped.viewAddress + fieldOffset); + } + // float public static void fput(float value, long addr) { @@ -221,6 +285,22 @@ return MappedObjectUnsafe.INSTANCE.getFloat(mapped.viewAddress + fieldOffset); } + public static void fvput(float value, long addr) { + MappedObjectUnsafe.INSTANCE.putFloatVolatile(null, addr, value); + } + + public static void fvput(MappedObject mapped, float value, int fieldOffset) { + MappedObjectUnsafe.INSTANCE.putFloatVolatile(null, mapped.viewAddress + fieldOffset, value); + } + + public static float fvget(long addr) { + return MappedObjectUnsafe.INSTANCE.getFloatVolatile(null, addr); + } + + public static float fvget(MappedObject mapped, int fieldOffset) { + return MappedObjectUnsafe.INSTANCE.getFloatVolatile(null, mapped.viewAddress + fieldOffset); + } + // long public static void jput(long value, long addr) { @@ -239,6 +319,22 @@ return MappedObjectUnsafe.INSTANCE.getLong(mapped.viewAddress + fieldOffset); } + public static void jvput(long value, long addr) { + MappedObjectUnsafe.INSTANCE.putLongVolatile(null, addr, value); + } + + public static void jvput(MappedObject mapped, long value, int fieldOffset) { + MappedObjectUnsafe.INSTANCE.putLongVolatile(null, mapped.viewAddress + fieldOffset, value); + } + + public static long jvget(long addr) { + return MappedObjectUnsafe.INSTANCE.getLongVolatile(null, addr); + } + + public static long lvget(MappedObject mapped, int fieldOffset) { + return MappedObjectUnsafe.INSTANCE.getLongVolatile(null, mapped.viewAddress + fieldOffset); + } + // address public static void aput(long value, long addr) { @@ -275,4 +371,20 @@ return MappedObjectUnsafe.INSTANCE.getDouble(mapped.viewAddress + fieldOffset); } + public static void dvput(double value, long addr) { + MappedObjectUnsafe.INSTANCE.putDoubleVolatile(null, addr, value); + } + + public static void dvput(MappedObject mapped, double value, int fieldOffset) { + MappedObjectUnsafe.INSTANCE.putDoubleVolatile(null, mapped.viewAddress + fieldOffset, value); + } + + public static double dvget(long addr) { + return MappedObjectUnsafe.INSTANCE.getDoubleVolatile(null, addr); + } + + public static double dvget(MappedObject mapped, int fieldOffset) { + return MappedObjectUnsafe.INSTANCE.getDoubleVolatile(null, mapped.viewAddress + fieldOffset); + } + } \ No newline at end of file Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java 2011-07-23 22:02:01 UTC (rev 3599) +++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java 2011-07-23 22:28:57 UTC (rev 3600) @@ -179,7 +179,11 @@ Pointer pointer = field.getAnnotation(Pointer.class); if ( pointer != null && field.getType() != long.class ) - throw new ClassFormatError("The @Pointer annotation can only be used on long fields. Field found: " + className + "." + field.getName() + ": " + field.getType()); + throw new ClassFormatError("The @Pointer annotation can only be used on long fields. @Pointer field found: " + className + "." + field.getName() + ": " + field.getType()); + + if ( Modifier.isVolatile(field.getModifiers()) && (pointer != null || field.getType() == ByteBuffer.class) ) + throw new ClassFormatError("The volatile keyword is not supported for @Pointer or ByteBuffer fields. Volatile field found: " + className + "." + field.getName() + ": " + field.getType()); + // quick hack long byteOffset = meta == null ? advancingOffset : meta.byteOffset(); long byteLength; @@ -209,7 +213,7 @@ if ( PRINT_ACTIVITY ) LWJGLUtil.log(MappedObjectTransformer.class.getSimpleName() + ": " + className + "." + field.getName() + " [type=" + field.getType().getSimpleName() + ", offset=" + byteOffset + "]"); - return new FieldInfo(byteOffset, byteLength, Type.getType(field.getType()), pointer != null); + return new FieldInfo(byteOffset, byteLength, Type.getType(field.getType()), Modifier.isVolatile(field.getModifiers()), pointer != null); } /** Removes final from methods that will be overriden by subclasses. */ @@ -395,7 +399,7 @@ visitIntNode(mv, (int)field.offset); mv.visitInsn(I2L); mv.visitInsn(LADD); - mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, field.isPointer ? "a" : field.type.getDescriptor().toLowerCase() + "get", "(J)" + field.type.getDescriptor()); + mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, field.getAccessType() + "get", "(J)" + field.type.getDescriptor()); mv.visitInsn(field.type.getOpcode(IRETURN)); mv.visitMaxs(3, 2); mv.visitEnd(); @@ -430,7 +434,7 @@ visitIntNode(mv, (int)field.offset); mv.visitInsn(I2L); mv.visitInsn(LADD); - mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, field.isPointer ? "a" : field.type.getDescriptor().toLowerCase() + "put", "(" + field.type.getDescriptor() + "J)V"); + mv.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, field.getAccessType() + "put", "(" + field.type.getDescriptor() + "J)V"); mv.visitInsn(RETURN); mv.visitMaxs(4, 4); mv.visitEnd(); @@ -933,13 +937,11 @@ private static InsnList generateFieldInstructions(final FieldInsnNode fieldInsn, final FieldInfo field) { final InsnList list = new InsnList(); - final String dataType = field.isPointer ? "a" : fieldInsn.desc.toLowerCase(); - if ( fieldInsn.getOpcode() == PUTFIELD ) { // stack: value, ref list.add(getIntNode((int)field.offset)); // stack: fieldOffset, value, ref - list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, dataType + "put", "(L" + MAPPED_OBJECT_JVM + ";" + fieldInsn.desc + "I)V")); + list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, field.getAccessType() + "put", "(L" + MAPPED_OBJECT_JVM + ";" + fieldInsn.desc + "I)V")); // stack - return list; } @@ -948,7 +950,7 @@ // stack: ref list.add(getIntNode((int)field.offset)); // stack: fieldOffset, ref - list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, dataType + "get", "(L" + MAPPED_OBJECT_JVM + ";I)" + fieldInsn.desc)); + list.add(new MethodInsnNode(INVOKESTATIC, MAPPED_HELPER_JVM, field.getAccessType() + "get", "(L" + MAPPED_OBJECT_JVM + ";I)" + fieldInsn.desc)); // stack: - return list; } @@ -1047,15 +1049,21 @@ final long offset; final long length; final Type type; + final boolean isVolatile; final boolean isPointer; - FieldInfo(final long offset, final long length, final Type type, final boolean isPointer) { + FieldInfo(final long offset, final long length, final Type type, final boolean isVolatile, final boolean isPointer) { this.offset = offset; this.length = length; this.type = type; + this.isVolatile = isVolatile; this.isPointer = isPointer; } + String getAccessType() { + return isPointer ? "a" : type.getDescriptor().toLowerCase() + (isVolatile ? "v" : ""); + } + } private static class MappedSubtypeInfo { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |