Removed stride and .configure. Mapped object view updates are now 50% faster. [Riven]
org.lwjgl.util.mapped.PrintBytecode is now functional. [Riven]
This commit is contained in:
parent
f0766fb6c4
commit
1f305d514a
|
@ -59,8 +59,8 @@ public class MappedObjectTests1 {
|
|||
{
|
||||
MappedFloat vecs1 = MappedFloat.malloc(1234);
|
||||
|
||||
assert (vecs1.stride == MappedFloat.SIZEOF);
|
||||
assert (vecs1.stride * 1234 == vecs1.backingByteBuffer().capacity());
|
||||
assert (vecs1.sizeof == MappedFloat.SIZEOF);
|
||||
assert (vecs1.sizeof * 1234 == vecs1.backingByteBuffer().capacity());
|
||||
assert (MappedFloat.SIZEOF * 1234 == vecs1.backingByteBuffer().capacity());
|
||||
}
|
||||
|
||||
|
@ -132,31 +132,6 @@ public class MappedObjectTests1 {
|
|||
}
|
||||
}
|
||||
|
||||
// test dup
|
||||
{
|
||||
int newStride = 16;
|
||||
int doOffset = 0;
|
||||
|
||||
vecs.view = 0;
|
||||
MappedFloat.configure(vecs, newStride, doOffset);
|
||||
MappedFloat dec2 = vecs.dup();
|
||||
MappedFloat.configure(dec2, newStride, doOffset);
|
||||
|
||||
String s1 = vecs.baseAddress + "," + vecs.viewAddress + "," + vecs.stride + "," + vecs.SIZEOF;
|
||||
String s2 = dec2.baseAddress + "," + dec2.viewAddress + "," + dec2.stride + "," + dec2.SIZEOF;
|
||||
// System.out.println(s1);
|
||||
// System.out.println(s2);
|
||||
assert (s1.equals(s2));
|
||||
|
||||
dec2.view++;
|
||||
|
||||
String s3 = vecs.baseAddress + "," + vecs.viewAddress + "," + vecs.stride + "," + vecs.SIZEOF;
|
||||
String s4 = dec2.baseAddress + "," + dec2.viewAddress + "," + dec2.stride + "," + dec2.SIZEOF;
|
||||
// System.out.println(s3);
|
||||
// System.out.println(s4);
|
||||
assert (!s3.equals(s4));
|
||||
}
|
||||
|
||||
// test newBuffer
|
||||
{
|
||||
long addr1 = MappedObjectUnsafe.getBufferBaseAddress(bb);
|
||||
|
|
|
@ -91,40 +91,8 @@ public class MappedObjectTests2 {
|
|||
vecs.view = 1;
|
||||
long a2 = vecs.viewAddress;
|
||||
assert (a2 - a1 == MappedVec3.SIZEOF);
|
||||
assert (a2 - a1 == vecs.stride);
|
||||
assert (a2 - a1 == vecs.sizeof);
|
||||
vecs.view = 0;
|
||||
}
|
||||
|
||||
int newStride = 16;
|
||||
|
||||
MappedVec3.configure(vecs, newStride, +4);
|
||||
assert (vecs.z == 0.1234f); // vecs[1].x ended up in vecs[0].z due to 1float offset
|
||||
|
||||
MappedVec3.configure(vecs, newStride, +8);
|
||||
assert (vecs.z == 0.0000f); // vecs[1].z ended up in vecs[0].z due to 2float offset
|
||||
|
||||
// test new stride
|
||||
{
|
||||
long a1 = vecs.viewAddress;
|
||||
vecs.view = 1;
|
||||
long a2 = vecs.viewAddress;
|
||||
assert (a2 - a1 == newStride);
|
||||
vecs.view = 0;
|
||||
}
|
||||
|
||||
// example: GPU => VBO => VTN
|
||||
{
|
||||
MappedVec3 v = MappedVec3.map(bb);
|
||||
MappedVec2 t = MappedVec2.map(bb);
|
||||
MappedVec3 n = MappedVec3.map(bb);
|
||||
|
||||
int stride = MappedVec3.SIZEOF + MappedVec2.SIZEOF + MappedVec3.SIZEOF;
|
||||
assert (stride == 32);
|
||||
|
||||
MappedVec3.configure(v, stride, 0);
|
||||
MappedVec2.configure(t, stride, MappedVec3.SIZEOF);
|
||||
MappedVec3.configure(n, stride, MappedVec3.SIZEOF + MappedVec2.SIZEOF);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,15 +4,14 @@
|
|||
|
||||
package org.lwjgl.test.mapped;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.lwjgl.opengl.Display;
|
||||
|
||||
public class MappedObjectWithLibrary
|
||||
{
|
||||
public static void testLWJGL() throws Exception
|
||||
{
|
||||
System.out.println(new File(System.getProperty("java.library.path")).getCanonicalPath());
|
||||
Display.create();
|
||||
}
|
||||
import java.io.File;
|
||||
|
||||
public class MappedObjectWithLibrary {
|
||||
|
||||
public static void testLWJGL() throws Exception {
|
||||
System.out.println(new File(System.getProperty("java.library.path")).getCanonicalPath());
|
||||
Display.create();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.lwjgl.util.mapped.MappedObjectClassLoader;
|
|||
import org.lwjgl.util.mapped.MappedObjectTransformer;
|
||||
|
||||
/** @author Riven */
|
||||
@SuppressWarnings("static-access")
|
||||
public class TestMappedObject {
|
||||
|
||||
static {
|
||||
|
@ -49,7 +50,6 @@ public class TestMappedObject {
|
|||
MappedObjectTransformer.register(MappedVec2.class);
|
||||
MappedObjectTransformer.register(MappedVec3.class);
|
||||
MappedObjectTransformer.register(MappedSomething.class);
|
||||
|
||||
MappedObjectTransformer.register(MappedObjectTests3.Xyz.class);
|
||||
|
||||
if ( MappedObjectClassLoader.fork(TestMappedObject.class, args) ) {
|
||||
|
@ -70,8 +70,8 @@ public class TestMappedObject {
|
|||
MappedObjectTests3.testForeach();
|
||||
MappedObjectTests3.testConstructor();
|
||||
MappedObjectTests3.testMappedSet();
|
||||
|
||||
MappedObjectWithLibrary.testLWJGL();
|
||||
|
||||
System.out.println("done");
|
||||
}
|
||||
|
||||
}
|
|
@ -58,7 +58,7 @@ final class MappedForeach<T extends MappedObject> implements Iterable<T> {
|
|||
}
|
||||
|
||||
public T next() {
|
||||
MappedHelper.put_view(mapped, this.index++);
|
||||
MappedHelper.put_view(mapped, this.index++, mapped.sizeof);
|
||||
return mapped;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ public class MappedHelper {
|
|||
|
||||
if ( sizeof % align != 0 )
|
||||
throw new IllegalStateException("sizeof not a multiple of alignment");
|
||||
mo.stride = sizeof;
|
||||
mo.sizeof = sizeof;
|
||||
|
||||
long addr = MappedObjectUnsafe.getBufferBaseAddress(buffer) + buffer.position();
|
||||
if ( addr % align != 0 )
|
||||
|
@ -79,19 +79,19 @@ public class MappedHelper {
|
|||
set.view(view);
|
||||
}
|
||||
|
||||
public static void put_view(MappedObject mapped, int view) {
|
||||
mapped.setViewAddress(mapped.baseAddress + view * mapped.stride);
|
||||
public static void put_view(MappedObject mapped, int view, int sizeof) {
|
||||
mapped.setViewAddress(mapped.baseAddress + view * sizeof);
|
||||
}
|
||||
|
||||
public static int get_view(MappedObject mapped) {
|
||||
return (int)(mapped.viewAddress - mapped.baseAddress) / mapped.stride;
|
||||
public static int get_view(MappedObject mapped, int sizeof) {
|
||||
return (int)(mapped.viewAddress - mapped.baseAddress) / sizeof;
|
||||
}
|
||||
|
||||
public static MappedObject dup(MappedObject src, MappedObject dst) {
|
||||
dst.baseAddress = src.baseAddress;
|
||||
dst.viewAddress = src.viewAddress;
|
||||
dst.stride = src.stride;
|
||||
dst.align = src.align;
|
||||
dst.sizeof = src.sizeof;
|
||||
dst.preventGC = src.preventGC;
|
||||
return dst;
|
||||
}
|
||||
|
@ -99,8 +99,8 @@ public class MappedHelper {
|
|||
public static MappedObject slice(MappedObject src, MappedObject dst) {
|
||||
dst.baseAddress = src.viewAddress; // !
|
||||
dst.viewAddress = src.viewAddress;
|
||||
dst.stride = src.stride;
|
||||
dst.align = src.align;
|
||||
dst.sizeof = src.sizeof;
|
||||
dst.preventGC = src.preventGC;
|
||||
return dst;
|
||||
}
|
||||
|
|
|
@ -63,12 +63,12 @@ public class MappedObject {
|
|||
/** The mapped object view memory address, in bytes. Read-only. */
|
||||
public long viewAddress;
|
||||
|
||||
/** The mapped object stride, in bytes. Read-only. */
|
||||
public int stride;
|
||||
|
||||
/** The mapped object memory alignment, in bytes. Read-only. */
|
||||
public int align;
|
||||
|
||||
/** The mapped object memory sizeof, in bytes. Read-only. */
|
||||
public int sizeof;
|
||||
|
||||
/**
|
||||
* Holds the value of sizeof of the sub-type of this MappedObject<br>
|
||||
* <br>
|
||||
|
@ -88,7 +88,7 @@ public class MappedObject {
|
|||
|
||||
/** Moves the current view to the next element. */
|
||||
public final void next() {
|
||||
setViewAddress(this.viewAddress + this.stride);
|
||||
setViewAddress(this.viewAddress + this.sizeof);
|
||||
}
|
||||
|
||||
final void setViewAddress(final long address) {
|
||||
|
@ -99,7 +99,7 @@ public class MappedObject {
|
|||
|
||||
final void checkAddress(final long address) {
|
||||
final long base = MappedObjectUnsafe.getBufferBaseAddress(preventGC);
|
||||
if ( address < base || preventGC.capacity() < (address - base + stride) )
|
||||
if ( address < base || preventGC.capacity() < (address - base + this.sizeof) )
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
|
@ -218,32 +218,6 @@ public class MappedObject {
|
|||
return new MappedForeach<T>(mapped, elementCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a newly initiated mapped object with the specified stride and offset.
|
||||
*
|
||||
* @throws IllegalStateException if view is not at index 0
|
||||
*/
|
||||
public static <T extends MappedObject> T configure(T mapped, int stride, int offset) {
|
||||
if ( mapped.baseAddress != mapped.viewAddress )
|
||||
throw new IllegalStateException("view must be zero");
|
||||
|
||||
if ( offset < 0 )
|
||||
throw new IllegalStateException("offset must not be negative: " + offset);
|
||||
if ( offset % mapped.align != 0 )
|
||||
throw new IllegalStateException("offset not a multiple of alignment: " + offset);
|
||||
|
||||
if ( stride < mapped.stride )
|
||||
throw new IllegalStateException("new stride must not be smaller than current stride: " + stride);
|
||||
if ( stride % mapped.align != 0 )
|
||||
throw new IllegalStateException("stride not a multiple of alignment: " + stride);
|
||||
|
||||
mapped.baseAddress += offset;
|
||||
mapped.viewAddress += offset;
|
||||
mapped.stride = stride;
|
||||
|
||||
return mapped;
|
||||
}
|
||||
|
||||
ByteBuffer preventGC;
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,7 +34,7 @@ public class MappedObjectTransformer {
|
|||
|
||||
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 boolean PRINT_BYTECODE = LWJGLUtil.DEBUG && LWJGLUtil.getPrivilegedBoolean("org.lwjgl.util.mapped.PrintBytecode");
|
||||
|
||||
static final Map<String, MappedSubtypeInfo> className_to_subtype;
|
||||
|
||||
|
@ -372,6 +372,7 @@ public class MappedObjectTransformer {
|
|||
if ( mappedSubtype == null ) {
|
||||
String mappedSetPrefix = jvmClassName(MappedSet.class);
|
||||
|
||||
// MappedSet.view
|
||||
outer:
|
||||
if ( "view".equals(fieldName) && className.startsWith(mappedSetPrefix) ) {
|
||||
if ( opcode == GETFIELD )
|
||||
|
@ -418,17 +419,23 @@ public class MappedObjectTransformer {
|
|||
|
||||
if ( opcode == GETFIELD ) {
|
||||
// stack: instance
|
||||
super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "get_view", "(L" + jvmClassName(MappedObject.class) + ";)I");
|
||||
pushInt(super.mv, mappedSubtype.sizeof);
|
||||
// stack: sizeof, instance
|
||||
super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "get_view", "(L" + jvmClassName(MappedObject.class) + ";I)I");
|
||||
// stack: view
|
||||
return;
|
||||
}
|
||||
if ( opcode == PUTFIELD ) {
|
||||
// stack: int, instance
|
||||
super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), "put_view", "(L" + jvmClassName(MappedObject.class) + ";I)V");
|
||||
// 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");
|
||||
// stack: -
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( "align".equals(fieldName) ) {
|
||||
if ( "align".equals(fieldName) || "sizeof".equals(fieldName) ) {
|
||||
if ( !"I".equals(typeName) )
|
||||
throw new IllegalStateException();
|
||||
|
||||
|
@ -436,7 +443,10 @@ public class MappedObjectTransformer {
|
|||
// stack: instance
|
||||
super.visitInsn(POP);
|
||||
// stack: -
|
||||
pushInt(super.mv, mappedSubtype.align);
|
||||
if ( "sizeof".equals(fieldName) )
|
||||
pushInt(super.mv, mappedSubtype.sizeof);
|
||||
else if ( "align".equals(fieldName) )
|
||||
pushInt(super.mv, mappedSubtype.align);
|
||||
// stack: int
|
||||
return;
|
||||
}
|
||||
|
@ -445,18 +455,6 @@ public class MappedObjectTransformer {
|
|||
}
|
||||
}
|
||||
|
||||
if ( "stride".equals(fieldName) ) {
|
||||
if ( !"I".equals(typeName) )
|
||||
throw new IllegalStateException();
|
||||
|
||||
if ( opcode == GETFIELD ) {
|
||||
// do not change a thing
|
||||
}
|
||||
if ( opcode == PUTFIELD ) {
|
||||
throwAccessErrorOnReadOnlyField(className, fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
if ( "baseAddress".equals(fieldName) || "viewAddress".equals(fieldName) ) {
|
||||
if ( !"J".equals(typeName) )
|
||||
throw new IllegalStateException();
|
||||
|
@ -476,6 +474,8 @@ public class MappedObjectTransformer {
|
|||
return;
|
||||
}
|
||||
|
||||
// now we're going to transform ByteBuffer-typed field access
|
||||
|
||||
if ( typeName.equals("L" + jvmClassName(ByteBuffer.class) + ";") ) {
|
||||
if ( opcode == PUTFIELD ) {
|
||||
throwAccessErrorOnReadOnlyField(className, fieldName);
|
||||
|
@ -500,30 +500,34 @@ public class MappedObjectTransformer {
|
|||
}
|
||||
}
|
||||
|
||||
// we're now going to transform the field access
|
||||
|
||||
if ( opcode == PUTFIELD ) {
|
||||
// stack: value, ref
|
||||
super.visitInsn(SWAP);
|
||||
// stack: ref, value
|
||||
super.visitFieldInsn(GETFIELD, mappedSubtype.className, "viewAddress", "J");
|
||||
// stack: long, value
|
||||
// stack: viewAddr, value
|
||||
super.visitLdcInsn(fieldOffset);
|
||||
// stack: long, long, value
|
||||
// stack: offset, viewAddr, value
|
||||
super.visitInsn(LADD);
|
||||
// stack: long, value
|
||||
// stack: fieldAddr, value
|
||||
super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), typeName.toLowerCase() + "put", "(" + typeName + "J)V");
|
||||
// stack -
|
||||
|
||||
return;
|
||||
}
|
||||
if ( opcode == GETFIELD ) {
|
||||
// stack: ref
|
||||
super.visitFieldInsn(GETFIELD, mappedSubtype.className, "viewAddress", "J");
|
||||
// stack: long
|
||||
// stack: viewAddr
|
||||
super.visitLdcInsn(fieldOffset);
|
||||
// stack: long, long
|
||||
// stack: fieldOffset, viewAddr
|
||||
super.visitInsn(LADD);
|
||||
// stack: long
|
||||
// stack: fieldAddr
|
||||
super.visitMethodInsn(INVOKESTATIC, jvmClassName(MappedHelper.class), typeName.toLowerCase() + "get", "(J)" + typeName);
|
||||
// stack: value
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -553,7 +557,7 @@ public class MappedObjectTransformer {
|
|||
else if ( value >= Short.MIN_VALUE && value <= Short.MAX_VALUE )
|
||||
mv.visitIntInsn(SIPUSH, value);
|
||||
else
|
||||
mv.visitLdcInsn(Integer.valueOf(value));
|
||||
mv.visitLdcInsn(value);
|
||||
}
|
||||
|
||||
static String jvmClassName(Class<?> type) {
|
||||
|
|
|
@ -44,8 +44,8 @@ public class MappedSet2 {
|
|||
public int view;
|
||||
|
||||
void view(int view) {
|
||||
MappedHelper.put_view(this.a, view);
|
||||
MappedHelper.put_view(this.b, view);
|
||||
MappedHelper.put_view(this.a, view, this.a.sizeof);
|
||||
MappedHelper.put_view(this.b, view, this.b.sizeof);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
|
|
|
@ -45,9 +45,9 @@ public class MappedSet3 {
|
|||
public int view;
|
||||
|
||||
void view(int view) {
|
||||
MappedHelper.put_view(this.a, view);
|
||||
MappedHelper.put_view(this.b, view);
|
||||
MappedHelper.put_view(this.c, view);
|
||||
MappedHelper.put_view(this.a, view, this.a.sizeof);
|
||||
MappedHelper.put_view(this.b, view, this.b.sizeof);
|
||||
MappedHelper.put_view(this.c, view, this.c.sizeof);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
|
|
|
@ -46,10 +46,10 @@ public class MappedSet4 {
|
|||
public int view;
|
||||
|
||||
void view(int view) {
|
||||
MappedHelper.put_view(this.a, view);
|
||||
MappedHelper.put_view(this.b, view);
|
||||
MappedHelper.put_view(this.c, view);
|
||||
MappedHelper.put_view(this.d, view);
|
||||
MappedHelper.put_view(this.a, view, this.a.sizeof);
|
||||
MappedHelper.put_view(this.b, view, this.b.sizeof);
|
||||
MappedHelper.put_view(this.c, view, this.c.sizeof);
|
||||
MappedHelper.put_view(this.d, view, this.d.sizeof);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
|
@ -58,5 +58,4 @@ public class MappedSet4 {
|
|||
this.c.next();
|
||||
this.d.next();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue