|
From: <sp...@us...> - 2011-07-14 16:54:32
|
Revision: 3587
http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3587&view=rev
Author: spasi
Date: 2011-07-14 16:54:25 +0000 (Thu, 14 Jul 2011)
Log Message:
-----------
Implemented .next() with bytecode transformation, 4x faster now.
Made method transformation a bit faster.
Modified Paths:
--------------
trunk/LWJGL/src/java/org/lwjgl/test/mapped/MappedObjectTests1.java
trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java
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/test/mapped/MappedObjectTests1.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/test/mapped/MappedObjectTests1.java 2011-07-13 22:15:35 UTC (rev 3586)
+++ trunk/LWJGL/src/java/org/lwjgl/test/mapped/MappedObjectTests1.java 2011-07-14 16:54:25 UTC (rev 3587)
@@ -89,6 +89,15 @@
vecs.view = 0;
}
+ // manipulate 'view' with next()
+ {
+ assert (vecs.view == 0);
+ vecs.next();
+ assert (vecs.view == 1);
+ assert (vecs.value != 1.1f); // old view
+ vecs.view = 0;
+ }
+
// test bounds checking
{
assert (vecs.view == 0);
Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java 2011-07-13 22:15:35 UTC (rev 3586)
+++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedHelper.java 2011-07-14 16:54:25 UTC (rev 3587)
@@ -87,6 +87,10 @@
return (int)(mapped.viewAddress - mapped.baseAddress) / sizeof;
}
+ public static void put_view_next(MappedObject mapped, int sizeof) {
+ mapped.setViewAddress(mapped.viewAddress + sizeof);
+ }
+
public static MappedObject dup(MappedObject src, MappedObject dst) {
dst.baseAddress = src.baseAddress;
dst.viewAddress = src.viewAddress;
Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java 2011-07-13 22:15:35 UTC (rev 3586)
+++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObject.java 2011-07-14 16:54:25 UTC (rev 3587)
@@ -86,12 +86,7 @@
*/
public int view;
- /** Moves the current view to the next element. */
- public final void next() {
- setViewAddress(this.viewAddress + this.sizeof);
- }
-
- final void setViewAddress(final long address) {
+ public final void setViewAddress(final long address) {
if ( CHECKS )
checkAddress(address);
this.viewAddress = address;
@@ -99,8 +94,9 @@
final void checkAddress(final long address) {
final long base = MappedObjectUnsafe.getBufferBaseAddress(preventGC);
- if ( address < base || preventGC.capacity() < (address - base + this.sizeof) )
- throw new IndexOutOfBoundsException();
+ final int offset = (int)(address - base);
+ if ( address < base || preventGC.capacity() < (offset + this.sizeof) )
+ throw new IndexOutOfBoundsException(Integer.toString(offset / sizeof));
}
final void checkRange(final int bytes) {
@@ -186,6 +182,12 @@
throw new InternalError("type not registered");
}
+ /** Moves the current view to the next element. */
+ public final void next() {
+ // any method that calls this method will have its call-site modified
+ throw new InternalError("type not registered");
+ }
+
/**
* Copies and amount of <code>SIZEOF</code> bytes, from the current
* mapped object, to the specified mapped object.
Modified: trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java 2011-07-13 22:15:35 UTC (rev 3586)
+++ trunk/LWJGL/src/java/org/lwjgl/util/mapped/MappedObjectTransformer.java 2011-07-14 16:54:25 UTC (rev 3587)
@@ -38,6 +38,9 @@
static final Map<String, MappedSubtypeInfo> className_to_subtype;
+ static final String MAPPED_OBJECT_JVM = jvmClassName(MappedObject.class);
+ static final String MAPPED_HELPER_JVM = jvmClassName(MappedHelper.class);
+
static {
className_to_subtype = new HashMap<String, MappedSubtypeInfo>();
@@ -56,7 +59,7 @@
// => IADD
// => PUTFIELD MyMappedType.view
//
- MappedSubtypeInfo info = new MappedSubtypeInfo(jvmClassName(MappedObject.class), -1, -1);
+ MappedSubtypeInfo info = new MappedSubtypeInfo(MAPPED_OBJECT_JVM, -1, -1);
className_to_subtype.put(info.className, info);
}
@@ -162,7 +165,7 @@
{
MappedSubtypeInfo mappedSubtype = className_to_subtype.get(className);
- if ( mappedSubtype != null && !mappedSubtype.className.equals(jvmClassName(MappedObject.class)) ) {
+ if ( mappedSubtype != null && !mappedSubtype.className.equals(MAPPED_OBJECT_JVM) ) {
if ( "<init>".equals(name) ) {
if ( !"()V".equals(desc) )
throw new IllegalStateException(className + " can only have a default constructor, found: " + desc);
@@ -170,7 +173,7 @@
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
- mv.visitMethodInsn(INVOKESPECIAL, jvmClassName(MappedObject.class), "<init>", "()V");
+ mv.visitMethodInsn(INVOKESPECIAL, MAPPED_OBJECT_JVM, "<init>", "()V");
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
@@ -181,7 +184,7 @@
}
}
- return new MappedInstanceMethodAdapter(className, name, desc, super.visitMethod(access, name, desc, signature, exceptions));
+ return new MappedInstanceMethodAdapter(access, className, name, desc, super.visitMethod(access, name, desc, signature, exceptions));
}
@Override
@@ -252,18 +255,26 @@
@Override
public void visitMethodInsn(int opcode, String className, String methodName, String signature) {
- if ( opcode == INVOKESPECIAL && className.equals(jvmClassName(MappedObject.class)) && "<init>".equals(methodName) && "()V".equals(signature) ) {
+ if ( opcode == INVOKESPECIAL && className.equals(MAPPED_OBJECT_JVM) && "<init>".equals(methodName) && "()V".equals(signature) ) {
// stack: instance
visitInsn(POP);
// stack: -
return;
}
- for ( MappedSubtypeInfo mappedType : className_to_subtype.values() ) {
- boolean isMapDirectMethod = (opcode == INVOKESTATIC && "map".equals(methodName) && className.equals(mappedType.className) && signature.equals("(JI)L" + jvmClassName(MappedObject.class) + ";"));
- boolean isMapBufferMethod = (opcode == INVOKESTATIC && "map".equals(methodName) && className.equals(mappedType.className) && signature.equals("(Ljava/nio/ByteBuffer;)L" + jvmClassName(MappedObject.class) + ";"));
- boolean isMallocMethod = (opcode == INVOKESTATIC && "malloc".equals(methodName) && className.equals(mappedType.className) && signature.equals("(I)L" + jvmClassName(MappedObject.class) + ";"));
+ MappedSubtypeInfo mappedType = className_to_subtype.get(className);
+ if ( mappedType != null && visitMappedMethod(opcode, className, methodName, signature, mappedType) )
+ return;
+ super.visitMethodInsn(opcode, className, methodName, signature);
+ }
+
+ private boolean visitMappedMethod(final int opcode, final String className, final String methodName, final String signature, final MappedSubtypeInfo mappedType) {
+ if ( opcode == INVOKESTATIC ) {
+ boolean isMapDirectMethod = "map".equals(methodName) && signature.equals("(JI)L" + MAPPED_OBJECT_JVM + ";");
+ boolean isMapBufferMethod = "map".equals(methodName) && signature.equals("(Ljava/nio/ByteBuffer;)L" + MAPPED_OBJECT_JVM + ";");
+ boolean isMallocMethod = "malloc".equals(methodName) && signature.equals("(I)L" + MAPPED_OBJECT_JVM + ";");
+
if ( (isMapDirectMethod || isMapBufferMethod) || isMallocMethod ) {
if ( isMallocMethod ) {
// stack: count
@@ -275,7 +286,7 @@
// stack: buffer
} else if ( isMapDirectMethod ) {
// stack: capacity, address
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "newBuffer", "(JI)L" + jvmClassName(ByteBuffer.class) + ";");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "newBuffer", "(JI)L" + jvmClassName(ByteBuffer.class) + ";");
// stack: buffer
}
@@ -294,12 +305,12 @@
// stack: int, buffer, new, new
pushInt(super.mv, mappedType.sizeof);
// stack: int, int, buffer, new, new
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "setup", "(L" + jvmClassName(MappedObject.class) + ";Ljava/nio/ByteBuffer;II)V");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "setup", "(L" + MAPPED_OBJECT_JVM + ";Ljava/nio/ByteBuffer;II)V");
// stack: new
- return;
+ return true;
}
-
- if ( opcode == INVOKEVIRTUAL && "dup".equals(methodName) && className.equals(mappedType.className) && signature.equals("()L" + jvmClassName(MappedObject.class) + ";") ) {
+ } else if ( opcode == INVOKEVIRTUAL ) {
+ if ( "dup".equals(methodName) && signature.equals("()L" + MAPPED_OBJECT_JVM + ";") ) {
// stack: this
super.visitTypeInsn(NEW, className);
// stack: new, this
@@ -307,12 +318,12 @@
// stack: new, new, this
super.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V");
// stack: new, this
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "dup", "(L" + jvmClassName(MappedObject.class) + ";L" + jvmClassName(MappedObject.class) + ";)L" + jvmClassName(MappedObject.class) + ";");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "dup", "(L" + MAPPED_OBJECT_JVM + ";L" + MAPPED_OBJECT_JVM + ";)L" + MAPPED_OBJECT_JVM + ";");
// stack: new
- return;
+ return true;
}
- if ( opcode == INVOKEVIRTUAL && "slice".equals(methodName) && className.equals(mappedType.className) && signature.equals("()L" + jvmClassName(MappedObject.class) + ";") ) {
+ if ( "slice".equals(methodName) && signature.equals("()L" + MAPPED_OBJECT_JVM + ";") ) {
// stack: this
super.visitTypeInsn(NEW, className);
// stack: new, this
@@ -320,46 +331,55 @@
// stack: new, new, this
super.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V");
// stack: new, this
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "slice", "(L" + jvmClassName(MappedObject.class) + ";L" + jvmClassName(MappedObject.class) + ";)L" + jvmClassName(MappedObject.class) + ";");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "slice", "(L" + MAPPED_OBJECT_JVM + ";L" + MAPPED_OBJECT_JVM + ";)L" + MAPPED_OBJECT_JVM + ";");
// stack: new
- return;
+ return true;
}
//
- if ( opcode == INVOKEVIRTUAL && "runViewConstructor".equals(methodName) && className.equals(mappedType.className) && "()V".equals(signature) ) {
+ if ( "runViewConstructor".equals(methodName) && "()V".equals(signature) ) {
// stack: this
super.visitInsn(DUP);
// stack: this, this
super.visitMethodInsn(INVOKEVIRTUAL, className, view_constructor_method, "()V");
// stack: this
- return;
+ return true;
}
//
- if ( opcode == INVOKEVIRTUAL && "copyTo".equals(methodName) && className.equals(mappedType.className) && signature.equals("(L" + jvmClassName(MappedObject.class) + ";)V") ) {
+ if ( "copyTo".equals(methodName) && signature.equals("(L" + MAPPED_OBJECT_JVM + ";)V") ) {
// stack: target, this
pushInt(super.mv, mappedType.sizeof);
// stack: sizeof, target, this
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "copy", "(L" + jvmClassName(MappedObject.class) + ";L" + jvmClassName(MappedObject.class) + ";I)V");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "copy", "(L" + MAPPED_OBJECT_JVM + ";L" + MAPPED_OBJECT_JVM + ";I)V");
// stack: -
- return;
+ return true;
}
- if ( opcode == INVOKEVIRTUAL && "copyRange".equals(methodName) && className.equals(mappedType.className) && signature.equals("(L" + jvmClassName(MappedObject.class) + ";I)V") ) {
+ if ( "copyRange".equals(methodName) && signature.equals("(L" + MAPPED_OBJECT_JVM + ";I)V") ) {
// stack: instances, target, this
pushInt(super.mv, mappedType.sizeof);
// stack: sizeof, instances, target, this
super.visitInsn(IMUL);
// stack: bytes, target, this
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "copy", "(L" + jvmClassName(MappedObject.class) + ";L" + jvmClassName(MappedObject.class) + ";I)V");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "copy", "(L" + MAPPED_OBJECT_JVM + ";L" + MAPPED_OBJECT_JVM + ";I)V");
// stack: -
- return;
+ return true;
}
+
+ if ( "next".equals(methodName) && "()V".equals(signature) ) {
+ // stack: this
+ pushInt(super.mv, mappedType.sizeof);
+ // stack: sizeof, this
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "put_view_next", "(L" + MAPPED_OBJECT_JVM + ";I)V");
+ // stack: -
+ return true;
+ }
}
- super.visitMethodInsn(opcode, className, methodName, signature);
+ return false;
}
private static void throwAccessErrorOnReadOnlyField(String className, String fieldName) {
@@ -384,11 +404,11 @@
if ( false )
break outer;
else if ( className.equals(jvmClassName(MappedSet2.class)) )
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "put_views", "(L" + jvmClassName(MappedSet2.class) + ";I)V");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "put_views", "(L" + jvmClassName(MappedSet2.class) + ";I)V");
else if ( className.equals(jvmClassName(MappedSet3.class)) )
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "put_views", "(L" + jvmClassName(MappedSet3.class) + ";I)V");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "put_views", "(L" + jvmClassName(MappedSet3.class) + ";I)V");
else if ( className.equals(jvmClassName(MappedSet4.class)) )
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "put_views", "(L" + jvmClassName(MappedSet4.class) + ";I)V");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "put_views", "(L" + jvmClassName(MappedSet4.class) + ";I)V");
else
break outer;
// stack: -
@@ -421,7 +441,7 @@
// stack: instance
pushInt(super.mv, mappedSubtype.sizeof);
// stack: sizeof, instance
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "get_view", "(L" + jvmClassName(MappedObject.class) + ";I)I");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "get_view", "(L" + MAPPED_OBJECT_JVM + ";I)I");
// stack: view
return;
}
@@ -429,7 +449,7 @@
// stack: view, instance
pushInt(super.mv, mappedSubtype.sizeof);
// stack: sizeof, view, instance
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "put_view", "(L" + jvmClassName(MappedObject.class) + ";II)V");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "put_view", "(L" + MAPPED_OBJECT_JVM + ";II)V");
// stack: -
return;
}
@@ -494,7 +514,7 @@
// stack: long, long
super.visitInsn(L2I);
// stack: int, long
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "newBuffer", "(JI)L" + jvmClassName(ByteBuffer.class) + ";");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, "newBuffer", "(JI)L" + jvmClassName(ByteBuffer.class) + ";");
// stack: buffer
return;
}
@@ -512,7 +532,7 @@
// stack: offset, viewAddr, value
super.visitInsn(LADD);
// stack: fieldAddr, value
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), typeName.toLowerCase() + "put", "(" + typeName + "J)V");
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, typeName.toLowerCase() + "put", "(" + typeName + "J)V");
// stack -
return;
@@ -525,7 +545,7 @@
// stack: fieldOffset, viewAddr
super.visitInsn(LADD);
// stack: fieldAddr
- super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), typeName.toLowerCase() + "get", "(J)" + typeName);
+ super.visitMethodInsn(INVOKESTATIC, MAPPED_HELPER_JVM, typeName.toLowerCase() + "get", "(J)" + typeName);
// stack: value
return;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|