Optimizations for lusearch. Serializable log is correctly done now. No TS yet.?

Jonathan Bell [2012-08-09 15:31:07]
Optimizations for lusearch. Serializable log is correctly done now. No TS yet.?
Filename
testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java
testcase-generation/src/edu/columbia/cs/psl/invivo/bench/WallaceLogExplorer.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/Log.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceExportRunner.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceUncaughtExceptionHandler.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldMethodVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingClassVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java
diff --git a/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java b/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java
index ae11330..5e4ffdb 100644
--- a/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java
+++ b/testcase-generation-tester/src/edu/columbia/cs/psl/invivo/example/ReaderUser.java
@@ -50,7 +50,7 @@ public class ReaderUser extends InputStreamReader {
 				charsRead = r.read(buf, 0, buf.length);
 				System.out.println(charsRead);
 //				System.out.println(buf);
-				Thread.sleep(100);
+//				Thread.sleep(100);
 //				System.out.println("Size" + Log.logsize);
 			}
 			c++;
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/WallaceLogExplorer.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/WallaceLogExplorer.java
new file mode 100644
index 0000000..225c4d6
--- /dev/null
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/bench/WallaceLogExplorer.java
@@ -0,0 +1,23 @@
+package edu.columbia.cs.psl.invivo.bench;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.ObjectInputStream;
+
+import edu.columbia.cs.psl.invivo.record.ExportedSerializableLog;
+
+public class WallaceLogExplorer {
+	public static void main(String[] args) throws Exception {
+		File f = new File("instrumented-test/wallace_serializable_1344515523846.log");
+		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
+		ExportedSerializableLog log = (ExportedSerializableLog) ois.readObject();
+		Object[] alog = ExportedSerializableLog.aLog;
+
+		char[] clog = ExportedSerializableLog.cLog;
+		byte[] blog = ExportedSerializableLog.bLog;
+
+		System.out.println(ExportedSerializableLog.aLog_fill);
+		System.out.println(ExportedSerializableLog.cLog_fill);
+		System.out.println(ExportedSerializableLog.dLog_fill);
+	}
+}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Log.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Log.java
index 6f9f52d..8e6da82 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Log.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Log.java
@@ -1,9 +1,12 @@
 package edu.columbia.cs.psl.invivo.record;

+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
 public class Log {
 	public static Object[] aLog = new Object[Constants.DEFAULT_LOG_SIZE];
-
-	public static Object lock = new Object();
+	public static Lock logLock = new ReentrantLock();
+//	public static Object lock = new Object();
 	public static int logsize = 0;
 	public static int aLog_fill;
 	public static void growaLog()
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceExportRunner.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceExportRunner.java
index 8ae7661..1454783 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceExportRunner.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceExportRunner.java
@@ -59,6 +59,7 @@ public class WallaceExportRunner extends Thread {
 	static WallaceExportRunner inst = new WallaceExportRunner();
 	public WallaceExportRunner() {
 		setDaemon(true);
+		setPriority(Thread.MAX_PRIORITY);
 	}

 	private static ExportedLog	log	= new ExportedLog();
@@ -68,15 +69,14 @@ public class WallaceExportRunner extends Thread {
 			XStream xstream = new XStream(new StaticReflectionProvider());
 			String xml = "";
 //			System.out.println("Waiting for the lock");
-			synchronized (Log.lock) {
-				ExportedLog.aLog = Log.aLog;
-
+			Log.logLock.lock();
+			ExportedLog.aLog = Log.aLog;

 				ExportedLog.aLog_fill = Log.aLog_fill;
 				Log.logsize = 0;
 				Log.aLog = new Object[Constants.DEFAULT_LOG_SIZE];
 				Log.aLog_fill = 0;
-			}
+			Log.logLock.unlock();
 				System.err.println("Serializing");
 				try{
 				xml = xstream.toXML(log);
@@ -94,12 +94,12 @@ public class WallaceExportRunner extends Thread {
 			FileWriter fw = new FileWriter(output);
 			fw.write(xml);
 			fw.close();
-			synchronized (Log.lock) {
-				Log.lock.notifyAll();
-			}
-			synchronized (Log.lock) {
-				Log.lock.notifyAll();
-			}
+//			synchronized (Log.lock) {
+//				Log.lock.notifyAll();
+//			}
+//			synchronized (Log.lock) {
+//				Log.lock.notifyAll();
+//			}


 		} catch (Exception exi) {
@@ -113,7 +113,8 @@ public class WallaceExportRunner extends Thread {
 		shouldExportSerializable = 0;
 		try {

-			synchronized (Log.lock) {
+			Log.logLock.lock();
+			{
 				ExportedSerializableLog.aLog = SerializableLog.aLog;
 				ExportedSerializableLog.aLog_fill = SerializableLog.aLog_fill;
 				ExportedSerializableLog.bLog = SerializableLog.bLog;
@@ -155,6 +156,7 @@ public class WallaceExportRunner extends Thread {
 				SerializableLog.sLog_fill = 0;
 				SerializableLog.aLog_fill = 0;
 			}
+			Log.logLock.unlock();
 //				System.err.println("Serializing serializable");
 				File output = new File("wallace_serializable_" + System.currentTimeMillis() + ".log");

@@ -166,12 +168,12 @@ public class WallaceExportRunner extends Thread {
 				ExportedLog.clearLog();
 //				System.err.println("Cleared serializable");
 //				System.out.println("Notifying; " + Log.logsize +";"+SerializableLog.logsize);
-				synchronized (Log.lock) {
-					Log.lock.notifyAll();
-				}
-				synchronized (Log.lock) {
-					Log.lock.notifyAll();
-				}
+//				synchronized (Log.lock) {
+//					Log.lock.notifyAll();
+//				}
+//				synchronized (Log.lock) {
+//					Log.lock.notifyAll();
+//				}
 		} catch (Exception exi) {
 //			System.err.println(exi.getMessage());
 		}
@@ -183,7 +185,8 @@ public class WallaceExportRunner extends Thread {
 	public static void _exportSerializable() {
 		if(shouldExportSerializable == -1)
 		{
-			System.out.println("Flagged shouldexport serializble");
+//			System.out.println("Flagged shouldexport serializble");
+			Thread.yield();
 			shouldExportSerializable = 1;
 			inst.interrupt();
 		}
@@ -192,6 +195,7 @@ public class WallaceExportRunner extends Thread {
 	public static void _export() {
 		if(shouldExport == -1)
 		{
+			Thread.yield();
 			shouldExport = 1;
 			inst.interrupt();
 		}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceUncaughtExceptionHandler.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceUncaughtExceptionHandler.java
index 2923928..602df4e 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceUncaughtExceptionHandler.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/WallaceUncaughtExceptionHandler.java
@@ -16,6 +16,7 @@ public class WallaceUncaughtExceptionHandler implements Thread.UncaughtException
 			e.printStackTrace();
 			System.err.println("Writing log");
 			WallaceExportRunner.export();
+			WallaceExportRunner.exportSerializable();
 			}
 		catch(Exception exi)
 		{
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java
index 9f15e57..0ba94b4 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java
@@ -10,6 +10,7 @@ import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 import org.objectweb.asm.commons.AdviceAdapter;
 import org.objectweb.asm.commons.GeneratorAdapter;
+import org.objectweb.asm.commons.LocalVariablesSorter;
 import org.objectweb.asm.commons.Method;
 import org.objectweb.asm.tree.FieldNode;

@@ -22,10 +23,10 @@ import edu.columbia.cs.psl.invivo.record.WallaceExportRunner;

 public class CloningAdviceAdapter extends GeneratorAdapter implements Opcodes {

-	private static final HashSet<String>	ignoredClasses		= new HashSet<String>();
-	private static boolean					flexibleLog			= false;
+	private static final HashSet<String> ignoredClasses = new HashSet<String>();
+	private static boolean flexibleLog = false;

-	private static final HashSet<String>	immutableClasses	= new HashSet<String>();
+	private static final HashSet<String> immutableClasses = new HashSet<String>();
 	static {
 		immutableClasses.add("Ljava/lang/Integer;");
 		immutableClasses.add("Ljava/lang/Long;");
@@ -53,28 +54,32 @@ public class CloningAdviceAdapter extends GeneratorAdapter implements Opcodes {
 		immutableClasses.add("L");

 	}
-	private String							className;
+	private String className;

-	public CloningAdviceAdapter(int api, MethodVisitor mv, int access, String name, String desc, String classname) {
+	private LocalVariablesSorter lvsorter;
+
+	public CloningAdviceAdapter(int api, MethodVisitor mv, int access, String name, String desc, String classname, LocalVariablesSorter lvsorter) {
 		super(api, mv, access, name, desc);
 		this.className = classname;
+		this.lvsorter = lvsorter;
 	}

 	/**
-	 * Precondition: Current element at the top of the stack is the element we need cloned Post condition: Current element at the top of the stack is
+	 * Precondition: Current element at the top of the stack is the element we
+	 * need cloned Post condition: Current element at the top of the stack is
 	 * the cloned element (and non-cloned is removed)
 	 */

 	protected void cloneValAtTopOfStack(String typeOfField) {
-		_generateClone(typeOfField, Constants.OUTER_COPY_METHOD_NAME, null);
+		_generateClone(typeOfField, Constants.OUTER_COPY_METHOD_NAME, null, false);
 	}

-	protected void cloneValAtTopOfStack(String typeOfField, String debug) {
-		_generateClone(typeOfField, Constants.OUTER_COPY_METHOD_NAME, debug);
+	protected void cloneValAtTopOfStack(String typeOfField, String debug, boolean secondElHasArrayLen) {
+		_generateClone(typeOfField, Constants.OUTER_COPY_METHOD_NAME, debug, secondElHasArrayLen);
 	}

 	protected void generateCloneInner(String typeOfField) {
-		_generateClone(typeOfField, Constants.INNER_COPY_METHOD_NAME, null);
+		_generateClone(typeOfField, Constants.INNER_COPY_METHOD_NAME, null, false);
 	}

 	public void println(String toPrint) {
@@ -88,29 +93,41 @@ public class CloningAdviceAdapter extends GeneratorAdapter implements Opcodes {
 		super.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
 	}

-	private void _generateClone(String typeOfField, String copyMethodToCall, String debug) {
+	private void _generateClone(String typeOfField, String copyMethodToCall, String debug, boolean secondElHasArrayLen) {
 		Type fieldType = Type.getType(typeOfField);

 		if (
-//				fieldType.getSort() == Type.ARRAY && fieldType.getElementType().getSort()
-//				||
-				fieldType.getSort() == Type.VOID ||
-				(fieldType.getSort() != Type.ARRAY && (fieldType.getSort() != Type.OBJECT || immutableClasses.contains(typeOfField)))) {
-//			println("reference> " + debug);
-//						println(debug);
-			//			println("Doing nothing");
+		// fieldType.getSort() == Type.ARRAY &&
+		// fieldType.getElementType().getSort()
+		// ||
+		fieldType.getSort() == Type.VOID || (fieldType.getSort() != Type.ARRAY && (fieldType.getSort() != Type.OBJECT || immutableClasses.contains(typeOfField)))) {
+			// println("reference> " + debug);
+			// println(debug);
+			// println("Doing nothing");
 			return;
 		}
 		if (fieldType.getSort() == Type.ARRAY) {
 			if (fieldType.getElementType().getSort() != Type.OBJECT || immutableClasses.contains(fieldType.getElementType().getDescriptor())) {
-//				println("array> " + debug);
+				// println("array> " + debug);

 				// Just need to duplicate the array
 				dup();
 				Label nullContinue = new Label();
 				ifNull(nullContinue);
-				dup();
-				visitInsn(ARRAYLENGTH);
+				if (secondElHasArrayLen) {
+					swap();
+					// pop();
+					// swap();
+					// dup();
+					// visitFieldInsn(GETSTATIC, "java/lang/System", "out",
+					// "Ljava/io/PrintStream;");
+					// swap();
+					// super.visitMethodInsn(INVOKEVIRTUAL,
+					// "java/io/PrintStream", "println", "(I)V");
+				} else {
+					dup();
+					visitInsn(ARRAYLENGTH);
+				}
 				dup();
 				newArray(Type.getType(fieldType.getDescriptor().substring(1)));
 				dupX2();
@@ -119,62 +136,97 @@ public class CloningAdviceAdapter extends GeneratorAdapter implements Opcodes {
 				dupX2();
 				swap();
 				super.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
-				visitLabel(nullContinue);
+				Label noNeedToPop = new Label();
+				if (secondElHasArrayLen) {
+					visitJumpInsn(GOTO, noNeedToPop);
+					visitLabel(nullContinue);
+					swap();
+					pop();
+				} else {
+					visitLabel(nullContinue);
+				}
+
+				visitLabel(noNeedToPop);

 			} else {
-//				println("heavy> " + debug);
+				// println("heavy> " + debug);
 				// Just use the reflective cloner
 				visitLdcInsn(debug);
 				invokeStatic(Type.getType(CloningUtils.class), Method.getMethod("Object clone(Object, String)"));
 				checkCast(fieldType);
 			}
-		} else if (fieldType.getClassName().contains("InputStream") || fieldType.getClassName().contains("OutputStream")
-				|| fieldType.getClassName().contains("Socket")) {
-			//Do nothing
+		} else if (fieldType.getClassName().contains("InputStream") || fieldType.getClassName().contains("OutputStream") || fieldType.getClassName().contains("Socket")) {
+			// Do nothing
 		} else {
-//			println("heavy> " + debug);
+			// println("heavy> " + debug);
 			visitLdcInsn(debug);
 			invokeStatic(Type.getType(CloningUtils.class), Method.getMethod("Object clone(Object, String)"));
 			checkCast(fieldType);

 		}
 	}
-
-	//	private static Object[] ar;
-//		private void magic()
-//		{
-//			new WallaceExportRunner().
-//		}
-	protected void logValueAtTopOfStackToArray(String logFieldOwner, String logFieldName, String logFieldTypeDesc, Type elementType,
-			boolean isStaticLoggingField, String debug) {
+
+	// private static Object[] ar;
+	// private void magic()
+	// {
+	// new WallaceExportRunner().
+	// }
+	protected void logValueAtTopOfStackToArray(String logFieldOwner, String logFieldName, String logFieldTypeDesc, Type elementType, boolean isStaticLoggingField, String debug,
+			boolean secondElHasArrayLen) {
 		int getOpcode = (isStaticLoggingField ? Opcodes.GETSTATIC : Opcodes.GETFIELD);
 		int putOpcode = (isStaticLoggingField ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD);
 		Label monitorStart = new Label();
 		Label monitorEndLabel = new Label();
 		int monitorIndx = 0;
-
-//		if (threadSafe) {
-			newLocal(Type.getType(logFieldTypeDesc)); //Needed for some reason, unkown? Don't remove though, otherwise ASM messes stuff up
-			newLocal(Type.getType(logFieldTypeDesc)); //Needed for some reason, unkown? Don't remove though, otherwise ASM messes stuff up
-			newLocal(Type.getType(logFieldTypeDesc)); //Needed for some reason, unkown? Don't remove though, otherwise ASM messes stuff up
-			newLocal(Type.getType(logFieldTypeDesc)); //Needed for some reason, unkown? Don't remove though, otherwise ASM messes stuff up
-			newLocal(Type.getType(logFieldTypeDesc)); //Needed for some reason, unkown? Don't remove though, otherwise ASM messes stuff up
-			newLocal(Type.getType(logFieldTypeDesc)); //Needed for some reason, unkown? Don't remove though, otherwise ASM messes stuff up
-			monitorIndx = newLocal(Type.getType("Ljava/lang/Object;"));
-			visitLabel(monitorStart);
-
-			//Lock
-			super.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(Log.class), "lock", "Ljava/lang/Object;");
-			dup();
-			super.visitVarInsn(ASTORE, monitorIndx);
-			super.monitorEnter();
-//		}
-		//Also acquire a read lock for the export lock
-		//		super.visitFieldInsn(GETSTATIC, Type.getInternalName(CloningUtils.class), "exportLock", Type.getDescriptor(ReadWriteLock.class));
-		//		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(ReadWriteLock.class), "readLock", "()Ljava/util/concurrent/locks/Lock;");
-		//		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "lock", "()V");
-
-
+
+		// if (threadSafe) {
+		// newLocal(Type.getType(logFieldTypeDesc)); // Needed for some reason,
+		// // unkown? Don't remove
+		// // though, otherwise ASM
+		// // messes stuff up
+		// newLocal(Type.getType(logFieldTypeDesc)); // Needed for some reason,
+		// // unkown? Don't remove
+		// // though, otherwise ASM
+		// // messes stuff up
+		// newLocal(Type.getType(logFieldTypeDesc)); // Needed for some reason,
+		// // unkown? Don't remove
+		// // though, otherwise ASM
+		// // messes stuff up
+		// newLocal(Type.getType(logFieldTypeDesc)); // Needed for some reason,
+		// // unkown? Don't remove
+		// // though, otherwise ASM
+		// // messes stuff up
+		// newLocal(Type.getType(logFieldTypeDesc)); // Needed for some reason,
+		// // unkown? Don't remove
+		// // though, otherwise ASM
+		// // messes stuff up
+		// newLocal(Type.getType(logFieldTypeDesc)); // Needed for some reason,
+		// // unkown? Don't remove
+		// // though, otherwise ASM
+		// // messes stuff up
+		// lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// monitorIndx = lvsorter.newLocal(Type.getType("Ljava/lang/Object;"));
+		// visitLabel(monitorStart);
+
+		// Lock
+		// super.visitFieldInsn(Opcodes.GETSTATIC,
+		// Type.getInternalName(Log.class), "lock", "Ljava/lang/Object;");
+		// dup();
+		// super.visitVarInsn(ASTORE, monitorIndx);
+		// super.monitorEnter();
+		// }
+		// Also acquire a read lock for the export lock
+		super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
+		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "lock", "()V");
+
 		// Grow the array if necessary
 		if (!isStaticLoggingField)
 			loadThis();
@@ -186,58 +238,75 @@ public class CloningAdviceAdapter extends GeneratorAdapter implements Opcodes {
 		Label labelForNoNeedToGrow = new Label();
 		super.ifCmp(Type.INT_TYPE, Opcodes.IFNE, labelForNoNeedToGrow);
 		// In this case, it's necessary to grow it
-			// Create the new array and initialize its size
-//		super.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Log.class), "grow"+logFieldName, "()V");
-
-		int newArray = newLocal(Type.getType(logFieldTypeDesc));
+		// Create the new array and initialize its size
+		// super.visitMethodInsn(Opcodes.INVOKESTATIC,
+		// Type.getInternalName(Log.class), "grow"+logFieldName, "()V");
+
+		int newArray = lvsorter.newLocal(Type.getType(logFieldTypeDesc));
 		if (!isStaticLoggingField)
 			loadThis();
-		super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-		super.arrayLength();
-		super.visitInsn(Opcodes.I2D);
-		super.visitLdcInsn(Constants.LOG_GROWTH_RATE);
-		super.visitInsn(Opcodes.DMUL);
-		super.visitInsn(Opcodes.D2I);
-
-		super.newArray(Type.getType(logFieldTypeDesc.substring(1))); // Bug in
-																		// ASM
-																		// prevents
-																		// us
-																		// from
-																		// doing
-																		// type.getElementType
-		super.storeLocal(newArray, Type.getType(logFieldTypeDesc));
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+		arrayLength();
+		visitInsn(Opcodes.I2D);
+		visitLdcInsn(Constants.LOG_GROWTH_RATE);
+		visitInsn(Opcodes.DMUL);
+		visitInsn(Opcodes.D2I);
+
+		newArray(Type.getType(logFieldTypeDesc.substring(1))); // Bug in
+																// ASM
+																// prevents
+																// us
+																// from
+																// doing
+																// type.getElementType
+		storeLocal(newArray, Type.getType(logFieldTypeDesc));
 		// Do the copy
 		if (!isStaticLoggingField)
 			loadThis();
-		super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-		super.visitInsn(Opcodes.ICONST_0);
-		super.loadLocal(newArray);
-		super.visitInsn(Opcodes.ICONST_0);
-		if (!isStaticLoggingField)
-			super.loadThis();
-		super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-		super.arrayLength();
-		super.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+		visitInsn(Opcodes.ICONST_0);
+		loadLocal(newArray);
+		visitInsn(Opcodes.ICONST_0);
+
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+		arrayLength();
+		visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V");

 		// array = newarray
-		if (!isStaticLoggingField)
-			super.loadThis();
-		super.loadLocal(newArray);
-		super.visitFieldInsn(putOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-
+
+		loadLocal(newArray);
+		visitFieldInsn(putOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+
 		visitLabel(labelForNoNeedToGrow);
 		// Load this into the end piece of the array
 		if (elementType.getSize() == 1) {
-			dup();
-			if (!isStaticLoggingField)
-				super.loadThis();
-			super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
-			swap();
-			if (!isStaticLoggingField)
-				super.loadThis();
-			super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
-			swap();
+			if (secondElHasArrayLen) {
+				/*
+				 * size buf
+				 */
+				dupX1();
+				/*
+				 * buf size buf
+				 */
+				visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+				dupX2();
+				pop();
+				/*
+				 * buf logfield size buf
+				 */
+				visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+				dupX2();
+				pop();
+				/*
+				 * buf logfield logsize size buf
+				 */
+			} else {
+				dup();
+				visitFieldInsn(getOpcode, logFieldOwner, logFieldName, logFieldTypeDesc);
+				swap();
+				visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+				swap();
+			}
 		} else if (elementType.getSize() == 2) {
 			dup2();
 			if (!isStaticLoggingField)
@@ -251,92 +320,88 @@ public class CloningAdviceAdapter extends GeneratorAdapter implements Opcodes {
 			dupX2();
 			pop();
 		}
-		cloneValAtTopOfStack(elementType.getDescriptor(), debug);
+		cloneValAtTopOfStack(elementType.getDescriptor(), debug, secondElHasArrayLen);

-		super.arrayStore(elementType);
+		arrayStore(elementType);
+		// if(secondElHasArrayLen)
+		// super.visitInsn(POP)

-		if (!isStaticLoggingField)
-			super.loadThis();
-		if (!isStaticLoggingField)
-			super.dup();
-		super.visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
+		visitFieldInsn(getOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());

 		super.visitInsn(Opcodes.ICONST_1);
 		super.visitInsn(Opcodes.IADD);
 		super.visitFieldInsn(putOpcode, logFieldOwner, logFieldName + "_fill", Type.INT_TYPE.getDescriptor());
-		//		println("Incremented fill for " + logFieldOwner+"."+logFieldName);
-		//Release the export lock
-		//		super.visitFieldInsn(GETSTATIC, Type.getInternalName(CloningUtils.class), "exportLock", Type.getDescriptor(ReadWriteLock.class));
-		//		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(ReadWriteLock.class), "readLock", "()Ljava/util/concurrent/locks/Lock;");
-		//		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "unlock", "()V");
-
-//		if (threadSafe) {
-			//Unlock
-			super.visitVarInsn(ALOAD, monitorIndx);
-			super.monitorExit();
-			visitLabel(monitorEndLabel);
-			Label endLbl = new Label();
-
-			if(elementType.getSort() == Type.ARRAY)
-			{
-				super.visitInsn(DUP);
-				super.visitInsn(ARRAYLENGTH);
-			}
-			else
-				super.visitInsn(ICONST_1);
-			super.visitVarInsn(ALOAD, monitorIndx);
-			super.monitorEnter();
-			super.visitFieldInsn(getOpcode, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
-			super.visitInsn(IADD);
-			super.visitInsn(DUP);
-			super.visitFieldInsn(PUTSTATIC, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
-
-			super.visitLdcInsn(Constants.MAX_LOG_SIZE);
-//			super.visitInsn(ISUB);
-			super.visitJumpInsn(IF_ICMPLE, endLbl);
-//			super.ifCmp(Type.INT_TYPE, Opcodes.IFGE, endLbl);
-			super.visitVarInsn(ALOAD, monitorIndx);
-			super.monitorExit();
-			if(logFieldOwner.equals(Type.getInternalName(SerializableLog.class)))
-				super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(WallaceExportRunner.class), "_exportSerializable", "()V");
-			else
-				super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(WallaceExportRunner.class), "_export", "()V");
-			super.visitVarInsn(ALOAD, monitorIndx);
-			super.monitorEnter();
-			super.visitFieldInsn(getOpcode, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
-			super.visitLdcInsn(Constants.VERY_MAX_LOG_SIZE);
-			super.visitJumpInsn(IF_ICMPLE, endLbl);
-
-
-//println("GOing to wait for " + logFieldOwner);
-//			super.visitLabel(tryStart);
-
-			super.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(Log.class), "lock", "Ljava/lang/Object;");
-			super.visitLdcInsn(500L);
-			super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "wait", "(J)V");
-
-//			super.visitLabel(tryEnd);
-
-//			super.visitJumpInsn(GOTO, endLbl);
-//			super.visitLabel(handlerStart);
-//			int n = newLocal(Type.getType(InterruptedException.class));
-//			super.visitVarInsn(ASTORE, n);
-//			super.visitInsn(POP);
-			visitLabel(endLbl);
-			super.visitVarInsn(ALOAD, monitorIndx);
-			super.monitorExit();
-//			super.visitLocalVariable(logFieldName + "_monitor", "Ljava/lang/Object;", null, monitorStart, monitorEndLabel, monitorIndx);
-//		}
+		// println("Incremented fill for " + logFieldOwner+"."+logFieldName);
+		// Release the export lock
+		// super.visitFieldInsn(GETSTATIC,
+		// Type.getInternalName(CloningUtils.class), "exportLock",
+		// Type.getDescriptor(ReadWriteLock.class));
+		// super.visitMethodInsn(INVOKEINTERFACE,
+		// Type.getInternalName(ReadWriteLock.class), "readLock",
+		// "()Ljava/util/concurrent/locks/Lock;");
+		// super.visitMethodInsn(INVOKEINTERFACE,
+		// Type.getInternalName(Lock.class), "unlock", "()V");
+
+		// if (threadSafe) {
+		// Unlock
+		// super.visitVarInsn(ALOAD, monitorIndx);
+		// super.monitorExit();
+		// visitLabel(monitorEndLabel);
+		Label endLbl = new Label();
+
+//		if (elementType.getSort() == Type.ARRAY) {
+//			super.visitInsn(DUP);
+//			super.visitInsn(ARRAYLENGTH);
+//		} else
+			super.visitInsn(ICONST_1);
+		// super.visitVarInsn(ALOAD, monitorIndx);
+		// super.monitorEnter();
+		super.visitFieldInsn(getOpcode, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
+		super.visitInsn(IADD);
+		super.visitInsn(DUP);
+		super.visitFieldInsn(PUTSTATIC, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
+
+		super.visitLdcInsn(Constants.MAX_LOG_SIZE);
+		// super.visitInsn(ISUB);
+		super.visitJumpInsn(IF_ICMPLE, endLbl);
+		// super.ifCmp(Type.INT_TYPE, Opcodes.IFGE, endLbl);
+		// super.visitVarInsn(ALOAD, monitorIndx);
+		// super.monitorExit();
+		if (logFieldOwner.equals(Type.getInternalName(SerializableLog.class)))
+			super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(WallaceExportRunner.class), "_exportSerializable", "()V");
+		else
+			super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(WallaceExportRunner.class), "_export", "()V");
+		// super.visitVarInsn(ALOAD, monitorIndx);
+		// super.monitorEnter();
+		super.visitFieldInsn(getOpcode, logFieldOwner, "logsize", Type.INT_TYPE.getDescriptor());
+		super.visitLdcInsn(Constants.VERY_MAX_LOG_SIZE);
+		super.visitJumpInsn(IF_ICMPLE, endLbl);
+
+		// println("GOing to wait for " + logFieldOwner);
+		// super.visitLabel(tryStart);
+
+		super.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(Log.class), "lock", "Ljava/lang/Object;");
+		super.visitLdcInsn(500L);
+		super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "wait", "(J)V");
+
+		// super.visitLabel(tryEnd);
+
+		// super.visitJumpInsn(GOTO, endLbl);
+		// super.visitLabel(handlerStart);
+		// int n = newLocal(Type.getType(InterruptedException.class));
+		// super.visitVarInsn(ASTORE, n);
+		// super.visitInsn(POP);
+		visitLabel(endLbl);
+//		super.visitVarInsn(ALOAD, monitorIndx);
+//		super.monitorExit();
+		super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
+		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "unlock", "()V");
+		// super.visitLocalVariable(logFieldName + "_monitor",
+		// "Ljava/lang/Object;", null, monitorStart, monitorEndLabel,
+		// monitorIndx);
+		// }

 	}
-	private void magic()
-	{
-		try{
-		Log.lock.wait(500);
-		}
-		catch(InterruptedException ex)
-		{
-
-		}
-	}
+
+
 }
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldMethodVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldMethodVisitor.java
index 0011fc8..2cc1339 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldMethodVisitor.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldMethodVisitor.java
@@ -29,7 +29,7 @@ public class MutatingFieldMethodVisitor extends CloningAdviceAdapter {
 	private String name;
 	private int access;
 	protected MutatingFieldMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc, String owner) {
-		super(api, mv, access, name, desc,owner);
+		super(api, mv, access, name, desc,owner, null);
 		thisMethod = Instrumenter.getAnnotatedMethod(owner, name, desc);
 		this.owner = owner;
 		this.name = name;
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingClassVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingClassVisitor.java
index 2b180cc..4f82504 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingClassVisitor.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingClassVisitor.java
@@ -7,6 +7,7 @@ import java.util.HashSet;

 import org.apache.log4j.Logger;
 import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
@@ -55,7 +56,7 @@ public class NonDeterministicLoggingClassVisitor extends ClassVisitor implements
 			LocalVariablesSorter sorter  = new LocalVariablesSorter(acc, desc, mv);
 			// CheckMethodAdapter cmv = new CheckMethodAdapter(mv);

-			NonDeterministicLoggingMethodVisitor cloningMV = new NonDeterministicLoggingMethodVisitor(Opcodes.ASM4, sorter, acc, name, desc, className, isFirstConstructor, analyzer);
+			NonDeterministicLoggingMethodVisitor cloningMV = new NonDeterministicLoggingMethodVisitor(Opcodes.ASM4, sorter, acc, name, desc, className, isFirstConstructor, analyzer, sorter);
 			if (name.equals("<init>"))
 				isFirstConstructor = false;
 			cloningMV.setClassVisitor(this);
@@ -98,14 +99,15 @@ public class NonDeterministicLoggingClassVisitor extends ClassVisitor implements
 				captureDesc += ")" + Type.getReturnType(mi.desc).getDescriptor();
 			}
 			MethodVisitor mv = super.visitMethod(opcode, mc.getCapturePrefix() + "_capture", captureDesc, null, null);
-			CloningAdviceAdapter caa = new CloningAdviceAdapter(Opcodes.ASM4, mv, opcode, mc.getCapturePrefix() + "_capture", captureDesc, className);
+			LocalVariablesSorter lvs = new LocalVariablesSorter(opcode, captureDesc, mv);
+			CloningAdviceAdapter caa = new CloningAdviceAdapter(Opcodes.ASM4, lvs, opcode, mc.getCapturePrefix() + "_capture", captureDesc, className,lvs);
 			Type[] args = Type.getArgumentTypes(captureDesc);
 			if(mi.name.equals("<init>"))
 			{
 				for (int i = 0; i < args.length; i++) {
 					caa.loadArg(i);
 				}
-				mv.visitMethodInsn(Opcodes.INVOKESPECIAL, mi.owner, mi.name, mi.desc);
+				caa.visitMethodInsn(Opcodes.INVOKESPECIAL, mi.owner, mi.name, mi.desc);
 				caa.loadArg(0);
 			}
 			else
@@ -115,13 +117,26 @@ public class NonDeterministicLoggingClassVisitor extends ClassVisitor implements
 				for (int i = 0; i < args.length; i++) {
 					caa.loadArg(i);
 				}
-				mv.visitMethodInsn(mi.getOpcode(), mi.owner, mi.name, mi.desc);
+				caa.visitMethodInsn(mi.getOpcode(), mi.owner, mi.name, mi.desc);
 				for (int i = 0; i < args.length; i++) {
 					if (args[i].getSort() == Type.ARRAY) {
+						boolean minimalCopy = (Type.getReturnType(methodDesc).getSort() == Type.INT);
+						if(minimalCopy)
+						{
+							caa.dup();
+							Label isNegative = new Label();
+							Label notNegative = new Label();
+							caa.visitJumpInsn(Opcodes.IFLT, isNegative);
+							caa.dup();
+							caa.visitJumpInsn(Opcodes.GOTO, notNegative);
+							caa.visitLabel(isNegative);
+							caa.visitInsn(ICONST_0);
+							caa.visitLabel(notNegative);
+						}
 						caa.loadArg(i);
 						//- (mi.getOpcode() == Opcodes.INVOKESTATIC ? 0 : 1)
 						caa.logValueAtTopOfStackToArray(MethodCall.getLogClassName(args[i]), "aLog", "[Ljava/lang/Object;",
-								args[i], true, mi.owner+"."+mi.name+"->_"+i+"\t"+args[i].getDescriptor()+"\t\t"+className);
+								args[i], true, mi.owner+"."+mi.name+"->_"+i+"\t"+args[i].getDescriptor()+"\t\t"+className,minimalCopy);
 						if (args[i].getSize() == 1)
 							caa.pop();
 						else
@@ -130,8 +145,8 @@ public class NonDeterministicLoggingClassVisitor extends ClassVisitor implements
 				}
 			}
 			caa.returnValue();
-			mv.visitMaxs(0, 0);
-			mv.visitEnd();
+			caa.visitMaxs(0, 0);
+			caa.visitEnd();
 		}
 	}

diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java
index dcf2b6a..714d343 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java
@@ -14,6 +14,7 @@ import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 import org.objectweb.asm.commons.AnalyzerAdapter;
+import org.objectweb.asm.commons.LocalVariablesSorter;
 import org.objectweb.asm.tree.MethodInsnNode;

 import edu.columbia.cs.psl.invivo.record.Constants;
@@ -61,8 +62,8 @@ public class NonDeterministicLoggingMethodVisitor extends CloningAdviceAdapter i
 	private boolean	isFirstConstructor;

 	protected NonDeterministicLoggingMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc, String classDesc,
-			boolean isFirstConstructor, AnalyzerAdapter analyzer) {
-		super(api, mv, access, name, desc,classDesc);
+			boolean isFirstConstructor, AnalyzerAdapter analyzer, LocalVariablesSorter lvs) {
+		super(api, mv, access, name, desc,classDesc, lvs);
 		this.name = name;
 		this.desc = desc;
 		this.classDesc = classDesc;
@@ -82,13 +83,8 @@ public class NonDeterministicLoggingMethodVisitor extends CloningAdviceAdapter i
 	@Override
 	public void visitEnd() {
 //		System.out.println(classDesc + " " + name);
-		try{
 		super.visitEnd();
-		}
-		catch(ArrayIndexOutOfBoundsException ex)
-		{
-			throw new ArrayIndexOutOfBoundsException("Processing maxs on " +classDesc + "."+ name);
-		}
+
 		parent.addFieldMarkup(methodCallsToClear);
 		parent.addCaptureMethodsToGenerate(captureMethodsToGenerate);
 	}
@@ -137,13 +133,13 @@ public class NonDeterministicLoggingMethodVisitor extends CloningAdviceAdapter i
 					}
 					mv.visitMethodInsn(invokeOpcode, classDesc, m.getCapturePrefix()+"_capture", captureDesc);
 					logValueAtTopOfStackToArray(m.getLogClassNmae(), m.getLogFieldName(), m.getLogFieldType().getDescriptor(), returnType, true,
-							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name);
+							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);
 				}
 				else
 				{
 					mv.visitMethodInsn(opcode, owner, name, desc);
 					logValueAtTopOfStackToArray(m.getLogClassNmae(), m.getLogFieldName(), m.getLogFieldType().getDescriptor(), returnType, true,
-							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name);
+							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);
 				}
 			}
 			else if(opcode == INVOKESPECIAL && name.equals("<init>") && nonDeterministicMethods.contains(owner + "." + name + ":" + desc) && !(owner.equals(Instrumenter.instrumentedClasses.get(classDesc).superName)
@@ -151,7 +147,7 @@ public class NonDeterministicLoggingMethodVisitor extends CloningAdviceAdapter i
 				super.visitMethodInsn(opcode, owner, name, desc);
 				if(analyzer.stack != null && analyzer.stack.size() > 0 && analyzer.stack.get(analyzer.stack.size()-1).equals(owner))
 					logValueAtTopOfStackToArray(MethodCall.getLogClassName(Type.getType("L"+owner+";")), "aLog", "[Ljava/lang/Object;", Type.getType("L"+owner+";"), true,
-							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name);
+							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);

 			}
 			else
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java
index 44b15da..a11e47e 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java
@@ -57,7 +57,7 @@ public class NonDeterministicReplayMethodVisitor extends CloningAdviceAdapter im

 	protected NonDeterministicReplayMethodVisitor(int api, MethodVisitor mv, int access, String name, String desc, String classDesc,
 			boolean isFirstConstructor) {
-		super(api, mv, access, name, desc,classDesc);
+		super(api, mv, access, name, desc,classDesc, null);
 		this.name = name;
 		this.desc = desc;
 		this.classDesc = classDesc;