Replay TS progress

Jonathan Bell [2012-08-09 20:15:50]
Replay TS progress
Filename
testcase-generation/src/edu/columbia/cs/psl/invivo/record/Constants.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedLog.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedSerializableLog.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/MethodCall.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/CloningAdviceAdapter.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldClassVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldMethodVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/NonDeterministicLoggingMethodVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayClassVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayMethodVisitor.java
testcase-generation/src/edu/columbia/cs/psl/invivo/replay/ReplayRunner.java
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Constants.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Constants.java
index 8adae83..9eb486a 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Constants.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/Constants.java
@@ -5,8 +5,8 @@ public interface Constants {
 	public static String PREV_VALUE_PREFIX = "__origValue_";
 //	public static String LOGGED_CALL_PREFIX = "__loggedValueAt_";

-	public static String LOG_DUMP_CLASS = "edu/columbia/cs/psl/invivo/record/Log";
-	public static String LOG_REPLAY_CLASS = "edu/columbia/cs/psl/invivo/record/ExportedLog";
+//	public static String LOG_DUMP_CLASS = "edu/columbia/cs/psl/invivo/record/Log";
+//	public static String LOG_REPLAY_CLASS = "edu/columbia/cs/psl/invivo/record/ExportedLog";

 	public static int DEFAULT_LOG_SIZE = 2000;
 	public static int MAX_LOG_SIZE = 40000000;
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedLog.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedLog.java
index d55ce7c..c16e511 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedLog.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedLog.java
@@ -1,12 +1,13 @@
 package edu.columbia.cs.psl.invivo.record;

+import java.util.HashMap;
+
 public class ExportedLog {
 	public static Object[] aLog = new Object[Constants.DEFAULT_LOG_SIZE];
 	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];

 	public static int aLog_fill;
-	public static int aLog_replayIndex;
-
+	public static HashMap<String, Integer> aLog_replayIndex = new HashMap<String, Integer>();
 	public static void clearLog() {
 		aLog = new Object[Constants.DEFAULT_LOG_SIZE];
 		aLog_owners =  new String[Constants.DEFAULT_LOG_SIZE];
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedSerializableLog.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedSerializableLog.java
index 9d419aa..468aedb 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedSerializableLog.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/ExportedSerializableLog.java
@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.util.HashMap;

 public class ExportedSerializableLog implements Serializable {
 	/**
@@ -21,8 +22,17 @@ public class ExportedSerializableLog implements Serializable {
 	public static short[] sLog = new short[Constants.DEFAULT_LOG_SIZE];
 	public static Object lock = new Object();
 	public static int aLog_fill, iLog_fill, jLog_fill, fLog_fill, dLog_fill, bLog_fill, zLog_fill, cLog_fill, sLog_fill;
-	public static int aLog_replayIndex , iLog_replayIndex, jLog_replayIndex, fLog_replayIndex, dLog_replayIndex, bLog_replayIndex, zLog_replayIndex, cLog_replayIndex, sLog_replayIndex;

+	public static HashMap<String,Integer> aLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> iLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> jLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> fLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> dLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> bLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> zLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> cLog_replayIndex = new HashMap<String,Integer>();
+	public static HashMap<String,Integer> sLog_replayIndex = new HashMap<String,Integer>();
+
 	public static String[] aLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
 	public static String[] iLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
 	public static String[] jLog_owners = new String[Constants.DEFAULT_LOG_SIZE];
@@ -101,5 +111,15 @@ public class ExportedSerializableLog implements Serializable {
 		zLog_owners = (String[]) ois.readObject();
 		cLog_owners = (String[]) ois.readObject();
 		sLog_owners = (String[]) ois.readObject();
+
+		ExportedSerializableLog.aLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.iLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.jLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.fLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.dLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.bLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.zLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.cLog_replayIndex = new HashMap<String,Integer>();
+		ExportedSerializableLog.sLog_replayIndex = new HashMap<String,Integer>();
 	}
 }
\ No newline at end of file
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/MethodCall.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/MethodCall.java
index dfc8949..1d3094b 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/MethodCall.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/MethodCall.java
@@ -90,7 +90,18 @@ public class MethodCall {
 		else
 			return Type.getInternalName(Log.class);
 	}
-	public String getLogClassNmae()
+	public static String getReplayClassName(Type t)
+	{
+		if(getLogClassName(t).equals(Type.getInternalName(SerializableLog.class)))
+			return Type.getInternalName(ExportedSerializableLog.class);
+		else
+			return Type.getInternalName(ExportedLog.class);
+	}
+	public String getReplayClassName()
+	{
+		return getReplayClassName(Type.getReturnType(methodDesc));
+	}
+	public String getLogClassName()
 	{
 		return getLogClassName(Type.getReturnType(methodDesc));
 	}
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 c19240a..a07d50d 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
@@ -175,55 +175,8 @@ public class CloningAdviceAdapter extends GeneratorAdapter implements Opcodes {
 			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
-		// 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
+		//Lock
 		super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
 		super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "lock", "()V");

diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldClassVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldClassVisitor.java
deleted file mode 100644
index 8982a64..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldClassVisitor.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.visitor;
-
-import java.util.HashMap;
-
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.commons.JSRInlinerAdapter;
-import org.objectweb.asm.tree.FieldNode;
-
-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.Instrumenter;
-import edu.columbia.cs.psl.invivo.record.struct.FieldExpression;
-
-public class MutatingFieldClassVisitor extends ClassVisitor {
-
-	public MutatingFieldClassVisitor(int api, ClassVisitor cv) {
-		super(api, cv);
-	}
-
-	private String className;
-
-	@Override
-	public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
-		// TODO Auto-generated method stub
-		if(interfaces == null)
-			interfaces = new String[]{"java/lang/Cloneable"};
-		else
-		{
-			//Add cloneable to the list of interfaces if it's not already there
-		}
-		super.visit(version, access, name, signature, superName, interfaces);
-		className = name;
-	}
-
-	@Override
-	public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
-		MethodVisitor smv = super.visitMethod(access, name, desc, signature, exceptions);
-		JSRInlinerAdapter  mv = new JSRInlinerAdapter(smv, access, name, desc, signature, exceptions);
-		if(name.equals("_copy") || name.equals("_setFieldsOn")) //FIXME this is a bad hack
-			return mv;
-		if (Instrumenter.getAnnotatedMethod(className, name, desc).isMutatesFieldsDirectly()) {
-			for (FieldExpression f : Instrumenter.getAnnotatedMethod(className, name, desc).getPutFieldInsns()) {
-//				System.out.println("\t" + f.getName());
-//				System.out.println("\t\t" + f.getParent());
-//				if(f.getParent() != null && f.getParent().getOpcode() == Opcodes.ALOAD && ((VarInsnNode) ((SimpleExpression) f.getParent()).getInsn()) == null )
-//				{
-//					System.out.println(f);
-//				}
-
-				if(f.getOwner().equals(className) && f.getOpcode() != Opcodes.PUTSTATIC)
-//				if (f.getParent() != null && f.getParent().getOpcode() == Opcodes.ALOAD && ((VarInsnNode) ((SimpleExpression) f.getParent()).getInsn()).var == 0)
-				{
-					putExpressions.put(f.getName(), f);
-				}
-			}
-		}
-		if (Instrumenter.getAnnotatedMethod(className, name, desc).isMutatesFields() || name.startsWith("_copy"))
-			return new MutatingFieldMethodVisitor(access, mv, access, name, desc, className);
-		else
-			return mv;
-	}
-
-	private HashMap<String, FieldExpression> putExpressions = new HashMap<String, FieldExpression>();
-
-	@Override
-	public void visitEnd() {
-		for (FieldExpression f : putExpressions.values()) {
-
-			FieldNode fn = new FieldNode(Opcodes.ASM4, Opcodes.ACC_PUBLIC,
-					Constants.BEEN_CLONED_PREFIX + f.getName(),
-					Type.BOOLEAN_TYPE.getDescriptor(), null, null);
-			fn.accept(cv);
-
-			FieldNode fn2 = new FieldNode(Opcodes.ASM4, Opcodes.ACC_PUBLIC,
-					Constants.PREV_VALUE_PREFIX + f.getName(),
-					f.getDesc(), null, null);
-
-			fn2.accept(cv);
-		}
-
-		super.visitEnd();
-	}
-}
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
deleted file mode 100644
index 2cc1339..0000000
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/record/visitor/MutatingFieldMethodVisitor.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package edu.columbia.cs.psl.invivo.record.visitor;
-
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.HashSet;
-
-import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-
-import edu.columbia.cs.psl.invivo.record.Constants;
-import edu.columbia.cs.psl.invivo.record.Instrumenter;
-import edu.columbia.cs.psl.invivo.record.struct.AnnotatedMethod;
-import edu.columbia.cs.psl.invivo.record.struct.Expression;
-import edu.columbia.cs.psl.invivo.record.struct.FieldExpression;
-import edu.columbia.cs.psl.invivo.record.struct.MethodExpression;
-
-public class MutatingFieldMethodVisitor extends CloningAdviceAdapter {
-	// private class FullFieldReference{
-	// private FullFieldReference parent;
-	// private FullFieldReference child;
-	// private Metho
-	// }
-	private ArrayList<FieldExpression> mutatedFieldExpressions = new ArrayList<FieldExpression>();
-	private HashSet<MethodExpression> methodsWeCallIndirectPut = new HashSet<MethodExpression>();
-	private AnnotatedMethod thisMethod;
-	private String owner;
-	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, null);
-		thisMethod = Instrumenter.getAnnotatedMethod(owner, name, desc);
-		this.owner = owner;
-		this.name = name;
-		this.access = access;
-		mutatedFieldExpressions.addAll(thisMethod.getPutFieldInsns());
-
-	}
-
-	private ArrayList<SimpleEntry<Expression, FieldExpression>> buildMethodsMutable(String parent, MethodExpression method) {
-		for (MethodExpression e : method.getMethod().functionsThatICall) {
-			if (e.getMethod().isMutatesFieldsDirectly()) {
-
-			}
-			if (e.getMethod().isMutatesFields()) {
-
-			}
-		}
-		return null;
-	}
-
-
-	/**
-	 * If this method directly changes fields, store a local variable with the
-	 * original value at time of change
-	 *
-	 */
-	@Override
-	public void visitMethodInsn(int opcode, String owner, String name, String desc) {
-		// TODO Auto-generated method stub
-		super.visitMethodInsn(opcode, owner, name, desc);
-	}
-
-	/**
-	 * When visiting a putfield, we need to log the value (duh)
-	 */
-	@Override
-	public void visitFieldInsn(int opcode, String owner, String name, String desc) {
-//		if (opcode == GETFIELD && desc.length() > 1) // Do this in the case of
-//														// objects only
-//		{
-//			// variablesToClear.put(name,desc);
-//			Label lblbForReadThrough = new Label();
-//			dup();
-//			super.visitFieldInsn(GETFIELD, owner, Constants.BEEN_CLONED_PREFIX + name, Type.BOOLEAN_TYPE.getDescriptor());
-//			visitJumpInsn(IFNE, lblbForReadThrough);
-//
-//			dup();
-//			dup();
-//			super.visitFieldInsn(GETSTATIC, "edu/columbia/cs/psl/invivo/record/CloningUtils", "cloner", "Lcom/rits/cloning/Cloner;");
-//			swap();
-//			super.visitFieldInsn(opcode, owner, name, desc);
-//			invokeVirtual(Type.getType(Cloner.class), Method.getMethod("Object deepClone(Object)"));
-//			checkCast(Type.getType(desc));
-//			super.visitFieldInsn(Opcodes.PUTFIELD, owner, Constants.PREV_VALUE_PREFIX + name, desc);
-//
-//			dup();
-//			visitLdcInsn(true);
-//			super.visitFieldInsn(Opcodes.PUTFIELD, owner, Constants.BEEN_CLONED_PREFIX + name, Type.BOOLEAN_TYPE.getDescriptor());
-//
-//			visitLabel(lblbForReadThrough);
-//
-//			super.visitFieldInsn(opcode, owner, name, desc);
-//		}
-		if(this.name.equals("<init>") || this.name.equals("<clinit>") || (this.access & Opcodes.ACC_STATIC) != 0)
-		{
-			super.visitFieldInsn(opcode, owner, name, desc);
-		}
-		else if (opcode == PUTFIELD && desc.length() == 1 ) // If we are going
-																// to do
-		// a putfield on a primitive do a simple copy
-		{
-			// variablesToClear.put(name,desc);
-//			dup();
-
-			super.visitFieldInsn(opcode, owner, name, desc);
-		} else if (opcode == PUTFIELD && desc.length() > 1 && owner.equals(this.owner)) // Need a copy on a
-		// putfield for objects too
-		{
-//			 variablesToClear.put(name,desc);
-			Label lblbForReadThrough = new Label();
-
-//			swap();
-//			dup();
-
-//			loadThis();
-//			super.visitFieldInsn(GETFIELD, owner, Constants.BEEN_CLONED_PREFIX + name, Type.BOOLEAN_TYPE.getDescriptor());
-//			visitJumpInsn(IFNE, lblbForReadThrough);
-
-//			dup();
-//			dup();
-
-			mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
-			mv.visitLdcInsn("Calling copy");
-			mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
-
-			loadThis();
-			loadThis();
-
-			super.visitFieldInsn(GETFIELD, owner, name, desc);
-			cloneValAtTopOfStack(desc);
-			super.visitFieldInsn(Opcodes.PUTFIELD, owner, Constants.PREV_VALUE_PREFIX + name, desc);
-
-//			dup();
-			loadThis();
-			super.push(true);
-			super.visitFieldInsn(Opcodes.PUTFIELD, owner, Constants.BEEN_CLONED_PREFIX + name, Type.BOOLEAN_TYPE.getDescriptor());
-
-//			visitLabel(lblbForReadThrough);
-//			swap();
-			super.visitFieldInsn(opcode, owner, name, desc);
-
-		} else
-			super.visitFieldInsn(opcode, owner, name, desc);
-
-//		super.visitFieldInsn(opcode, owner, name, desc);
-	}
-}
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 714d343..94b4e4c 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
@@ -132,13 +132,13 @@ public class NonDeterministicLoggingMethodVisitor extends CloningAdviceAdapter i
 						captureDesc+=")"+Type.getReturnType(desc).getDescriptor();
 					}
 					mv.visitMethodInsn(invokeOpcode, classDesc, m.getCapturePrefix()+"_capture", captureDesc);
-					logValueAtTopOfStackToArray(m.getLogClassNmae(), m.getLogFieldName(), m.getLogFieldType().getDescriptor(), returnType, true,
+					logValueAtTopOfStackToArray(m.getLogClassName(), m.getLogFieldName(), m.getLogFieldType().getDescriptor(), returnType, true,
 							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,
+					logValueAtTopOfStackToArray(m.getLogClassName(), m.getLogFieldName(), m.getLogFieldType().getDescriptor(), returnType, true,
 							owner+"."+name + "\t" + desc+"\t\t"+classDesc+"."+this.name,false);
 				}
 			}
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayClassVisitor.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayClassVisitor.java
index 9f3ee70..c92d038 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayClassVisitor.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/NonDeterministicReplayClassVisitor.java
@@ -72,70 +72,7 @@ public class NonDeterministicReplayClassVisitor extends ClassVisitor implements
 	@Override
 	public void visitEnd() {
 		super.visitEnd();
-//		for(String logFieldName : captureMethodsToGenerate.keySet())
-//		{
-//			MethodInsnNode mi = captureMethodsToGenerate.get(logFieldName);
-//			String methodDesc = mi.desc;
-//
-//			String captureDesc = mi.desc;
-//			if(mi.getOpcode() != Opcodes.INVOKESTATIC)
-//			{
-//				//Need to put owner of the method on the top of the args list
-//				captureDesc = "(L" +  mi.owner +";";
-//				for(Type t : Type.getArgumentTypes(mi.desc))
-//					captureDesc += t.getDescriptor();
-//				captureDesc+=")"+Type.getReturnType(mi.desc).getDescriptor();
-//			}
-//			MethodVisitor mv = super.visitMethod(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, logFieldName+"_capture", captureDesc, null, null);
-//			CloningAdviceAdapter caa = new CloningAdviceAdapter(Opcodes.ASM4, mv, Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC,logFieldName+"_capture", captureDesc, className);
-//			Type[] args = Type.getArgumentTypes(captureDesc);
-//			for(int i = 0; i < args.length ; i++)
-//			{
-//				caa.loadArg(i);
-//			}
-//			mv.visitMethodInsn(mi.getOpcode(), mi.owner, mi.name, mi.desc);
-//			for(int i = 0; i< args.length; i++)
-//			{
-//				if(args[i].getSort() == Type.ARRAY)
-//				{
-//					caa.loadArg(i);
-//
-//					//caa.logValueAtTopOfStackToArray(className + Constants.LOG_CLASS_SUFFIX, logFieldName+"_"+(i-(mi.getOpcode() == Opcodes.INVOKESTATIC ? 0 : 1)), "["+args[i].getDescriptor(), args[i], true);
-//
-//					if(args[i].getSize() == 1)
-//						caa.pop();
-//					else
-//						caa.pop2();
-//				}
-//			}
-//			caa.returnValue();
-//			mv.visitMaxs(0, 0);
-//			mv.visitEnd();
-//		}

-		/*{
-			MethodVisitor mv = this.visitMethod(Opcodes.ACC_PUBLIC, Constants.INNER_COPY_METHOD_NAME, "()L"+className+";", null, null);
-			CloningAdviceAdapter cloningAdapter = new CloningAdviceAdapter(Opcodes.ASM4, mv, Opcodes.ACC_PUBLIC, Constants.INNER_COPY_METHOD_NAME, "()L"+className+";", className);
-			//cloningAdapter.generateCopyMethod();
-			mv.visitMaxs(0, 0);
-			cloningAdapter.returnValue();
-			mv.visitEnd();
-		}
-		{
-			MethodVisitor mv = this.visitMethod(Opcodes.ACC_PUBLIC, Constants.OUTER_COPY_METHOD_NAME, "()L"+className+";", null, null);
-			CloningAdviceAdapter cloningAdapter = new CloningAdviceAdapter(Opcodes.ASM4, mv, Opcodes.ACC_PUBLIC, Constants.OUTER_COPY_METHOD_NAME, "()L"+className+";", className);
-			//cloningAdapter.generateOuterCopyMethod();
-			mv.visitMaxs(0, 0);
-			cloningAdapter.returnValue();
-			mv.visitEnd();
-		}
-		{
-			MethodVisitor mv = this.visitMethod(Opcodes.ACC_PUBLIC, Constants.SET_FIELDS_METHOD_NAME, "(L"+className+";)L"+className+";", null, null);
-			CloningAdviceAdapter cloningAdapter = new CloningAdviceAdapter(Opcodes.ASM4, mv, Opcodes.ACC_PUBLIC, Constants.SET_FIELDS_METHOD_NAME, "(L"+className+";)L"+className+";", className);
-			mv.visitMaxs(0, 0);
-			cloningAdapter.returnValue();
-			mv.visitEnd();
-		}*/
 	}
 	public String getClassName() {
 		return className;
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 a11e47e..11401fb 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
@@ -19,7 +19,9 @@ import org.objectweb.asm.tree.MethodInsnNode;

 import edu.columbia.cs.psl.invivo.record.CloningUtils;
 import edu.columbia.cs.psl.invivo.record.Constants;
+import edu.columbia.cs.psl.invivo.record.ExportedLog;
 import edu.columbia.cs.psl.invivo.record.Instrumenter;
+import edu.columbia.cs.psl.invivo.record.Log;
 import edu.columbia.cs.psl.invivo.record.MethodCall;
 import edu.columbia.cs.psl.invivo.record.visitor.CloningAdviceAdapter;

@@ -88,7 +90,47 @@ public class NonDeterministicReplayMethodVisitor extends CloningAdviceAdapter im
 		super.visitLineNumber(line, start);
 		lineNumber = line;
 	}
-
+	private void loadReplayIndex(String className, String fieldName)
+	{
+		/*
+		  GETSTATIC edu/columbia/cs/psl/invivo/record/ExportedLog.aLog_replayIndex : Ljava/util/HashMap;
+		    INVOKESTATIC java/lang/Thread.currentThread()Ljava/lang/Thread;
+		    INVOKEVIRTUAL java/lang/Thread.getName()Ljava/lang/String;
+		    INVOKEVIRTUAL java/util/HashMap.containsKey(Ljava/lang/Object;)Z
+		    IFNE L1
+		   L2
+		    LINENUMBER 45 L2
+		    GETSTATIC edu/columbia/cs/psl/invivo/record/ExportedLog.aLog_replayIndex : Ljava/util/HashMap;
+		    INVOKESTATIC java/lang/Thread.currentThread()Ljava/lang/Thread;
+		    INVOKEVIRTUAL java/lang/Thread.getName()Ljava/lang/String;
+		    ICONST_0
+		    INVOKESTATIC java/lang/Integer.valueOf(I)Ljava/lang/Integer;
+		    INVOKEVIRTUAL java/util/HashMap.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+		    POP
+		   L1
+		    LINENUMBER 46 L1
+		   FRAME SAME
+		    GETSTATIC edu/columbia/cs/psl/invivo/record/ExportedLog.aLog_replayIndex : Ljava/util/HashMap;
+		    INVOKESTATIC java/lang/Thread.currentThread()Ljava/lang/Thread;
+		    INVOKEVIRTUAL java/lang/Thread.getName()Ljava/lang/String;
+		    INVOKEVIRTUAL java/util/HashMap.get(Ljava/lang/Object;)Ljava/lang/Object;
+		    CHECKCAST java/lang/Integer
+		    INVOKEVIRTUAL java/lang/Integer.intValue()I
+		 */
+		super.visitFieldInsn(GETSTATIC, Type.getInternalName(ExportedLog.class), fieldName+"_replayIndex", "Ljava/util/HashMap;");
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "containsKey", "(Ljava/lang/Object;)Z");
+		Label exists = new Label();
+		super.visitFieldInsn(GETSTATIC, Type.getInternalName(ExportedLog.class), fieldName+"_replayIndex", "Ljava/util/HashMap;");
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "currentThread", "()Ljava/lang/Thread;");
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Thread.class), "getName", "()Ljava/lang/String;");
+		super.visitInsn(ICONST_0);
+		super.visitMethodInsn(INVOKESTATIC, Type.getInternalName(Integer.class), "valueOf", "(I)java/lang/Integer;");
+		super.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(HashMap.class), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+
+		super.visitJumpInsn(Opcodes.IFNE, exists);
+	}
 	private HashMap<String, MethodInsnNode> captureMethodsToGenerate = new HashMap<String, MethodInsnNode>();
 	@Override
 	public void visitMethodInsn(int opcode, String owner, String name, String desc) {
@@ -122,10 +164,8 @@ public class NonDeterministicReplayMethodVisitor extends CloningAdviceAdapter im
 				Label startOfPlayBack = new Label();


-				//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");
+				super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
+				super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "lock", "()V");

 				logger.debug("Adding field in MV to list " + m.getLogFieldName());
 				methodCallsToClear.add(m);
@@ -145,27 +185,27 @@ public class NonDeterministicReplayMethodVisitor extends CloningAdviceAdapter im
 							 * stack (grows down):
 							 * dest (fill not incremented yet)
 							 */
-							mv.visitFieldInsn(GETSTATIC, Constants.LOG_REPLAY_CLASS,
+							String replayClassName = MethodCall.getReplayClassName(t);
+							mv.visitFieldInsn(GETSTATIC, replayClassName,
 									MethodCall.getLogFieldName(t),
 									MethodCall.getLogFieldType(t).getDescriptor());
-							mv.visitFieldInsn(GETSTATIC,Constants.LOG_REPLAY_CLASS,
+							mv.visitFieldInsn(GETSTATIC,replayClassName,
 									MethodCall.getLogFieldName(t)+"_replayIndex",
 									"I");
 							mv.visitInsn(DUP);
-							mv.visitFieldInsn(GETSTATIC, Constants.LOG_REPLAY_CLASS, MethodCall.getLogFieldName(t)+"_fill", "I");
+							mv.visitFieldInsn(GETSTATIC, replayClassName, MethodCall.getLogFieldName(t)+"_fill", "I");
 							Label fallThrough = new Label();


 							mv.visitJumpInsn(Opcodes.IF_ICMPNE, fallThrough);
 							mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ReplayRunner.class), "loadNextLog", "()V");
 							pop();
-							mv.visitFieldInsn(GETSTATIC, Constants.LOG_REPLAY_CLASS,
+							mv.visitFieldInsn(GETSTATIC, replayClassName,
 									MethodCall.getLogFieldName(t) +"_replayIndex",
 									"I");
 							visitLabel(fallThrough);

 							arrayLoad(t);
-//							mv.visitTypeInsn(Opcodes.CHECKCAST, t.getInternalName());

 							/*
 							 * stack (grows down):
@@ -201,16 +241,16 @@ public class NonDeterministicReplayMethodVisitor extends CloningAdviceAdapter im
 							 * 0
 							 */

-							mv.visitFieldInsn(GETSTATIC, Constants.LOG_REPLAY_CLASS,
+							mv.visitFieldInsn(GETSTATIC, replayClassName,
 									MethodCall.getLogFieldName(t),
 									MethodCall.getLogFieldType(t).getDescriptor());
-							mv.visitFieldInsn(GETSTATIC, Constants.LOG_REPLAY_CLASS,
+							mv.visitFieldInsn(GETSTATIC, replayClassName,
 									MethodCall.getLogFieldName(t)+"_replayIndex",
 									"I");
 							mv.visitInsn(DUP);
 							mv.visitInsn(ICONST_1);
 							mv.visitInsn(IADD);
-							mv.visitFieldInsn(PUTSTATIC, Constants.LOG_REPLAY_CLASS,
+							mv.visitFieldInsn(PUTSTATIC, replayClassName,
 									MethodCall.getLogFieldName(t) +"_replayIndex",
 									"I");
 							arrayLoad(t);
@@ -264,17 +304,17 @@ public class NonDeterministicReplayMethodVisitor extends CloningAdviceAdapter im
 				if (returnType.getSort() == Type.VOID)
 					mv.visitInsn(NOP);
 				else {
-					mv.visitFieldInsn(GETSTATIC, Constants.LOG_REPLAY_CLASS,
+					mv.visitFieldInsn(GETSTATIC, m.getReplayClassName(),
 							m.getLogFieldName(),
 							m.getLogFieldType().getDescriptor());
-					mv.visitFieldInsn(GETSTATIC, Constants.LOG_REPLAY_CLASS, m.getLogFieldName()+"_replayIndex", "I");
+					mv.visitFieldInsn(GETSTATIC, m.getReplayClassName(), m.getLogFieldName()+"_replayIndex", "I");
 					mv.visitInsn(DUP);
 					Label fallThrough = new Label();
-					mv.visitFieldInsn(GETSTATIC, Constants.LOG_REPLAY_CLASS, m.getLogFieldName()+"_fill", "I");
+					mv.visitFieldInsn(GETSTATIC, m.getReplayClassName(), m.getLogFieldName()+"_fill", "I");
 					mv.visitJumpInsn(Opcodes.IF_ICMPNE, fallThrough);
 					mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ReplayRunner.class), "loadNextLog", "()V");
 					mv.visitInsn(POP);
-					mv.visitFieldInsn(GETSTATIC, Constants.LOG_REPLAY_CLASS,
+					mv.visitFieldInsn(GETSTATIC, m.getReplayClassName(),
 							m.getLogFieldName() +"_replayIndex",
 							"I");

@@ -282,14 +322,12 @@ public class NonDeterministicReplayMethodVisitor extends CloningAdviceAdapter im
 					mv.visitInsn(DUP);
 					mv.visitInsn(ICONST_1);
 					mv.visitInsn(IADD);
-					mv.visitFieldInsn(PUTSTATIC, Constants.LOG_REPLAY_CLASS, m.getLogFieldName()+"_replayIndex", "I");
+					mv.visitFieldInsn(PUTSTATIC, m.getReplayClassName(), m.getLogFieldName()+"_replayIndex", "I");
 					arrayLoad(m.getReturnType());
 				}
-				//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");
-//
+				//Unlock
+				super.visitFieldInsn(GETSTATIC, Type.getInternalName(Log.class), "logLock", Type.getDescriptor(Lock.class));
+				super.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Lock.class), "unlock", "()V");

 			} else {
 				super.visitMethodInsn(opcode, owner, name, desc);
diff --git a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/ReplayRunner.java b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/ReplayRunner.java
index 5facba1..ae3b1b2 100644
--- a/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/ReplayRunner.java
+++ b/testcase-generation/src/edu/columbia/cs/psl/invivo/replay/ReplayRunner.java
@@ -1,7 +1,9 @@
 package edu.columbia.cs.psl.invivo.replay;

 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileWriter;
+import java.io.ObjectInputStream;
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
@@ -9,39 +11,50 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.Arrays;

+import org.objectweb.asm.Type;
+
 import com.thoughtworks.xstream.XStream;

 import edu.columbia.cs.psl.invivo.record.CloningUtils;
 import edu.columbia.cs.psl.invivo.record.Constants;
 import edu.columbia.cs.psl.invivo.record.ExportedLog;
+import edu.columbia.cs.psl.invivo.record.ExportedSerializableLog;
+import edu.columbia.cs.psl.invivo.record.Log;
 import edu.columbia.cs.psl.invivo.record.xstream.StaticReflectionProvider;

 public class ReplayRunner {
-	public static String[]	logFiles;
-	private static int		nextLog	= 0;
+	public static String[] logFiles;
+	public static String[] serializableLogFiles;
+
+	private static int nextLog = 0;
+	private static int nextSerializableLog = 0;

-	public static void loadNextLog() {
+	public static void loadNextLog(String logClass) {
 		try {
-			CloningUtils.exportLock.writeLock().lock();
-			_loadNextLog();
-			CloningUtils.exportLock.writeLock().unlock();
+			Log.logLock.lock();
+			_loadNextLog(logClass);
+			Log.logLock.unlock();
 		} catch (Exception exi) {
 			exi.printStackTrace();
 		}
 	}

-	private static void _loadNextLog() {
+	private static void _loadNextLog(String logClass) {
 		try {
-			XStream xstream = new XStream(new StaticReflectionProvider());
-			Object o = xstream.fromXML(new File(logFiles[nextLog]));
-//			ExportedLog.aLog_replayIndex = 1;
-//			ExportedLog.iLog_replayIndex = 1;
-			nextLog++;
+			if (logClass.contains("Serializable")) {
+				ObjectInputStream is = new ObjectInputStream(new FileInputStream(serializableLogFiles[nextSerializableLog]));
+				ExportedSerializableLog el = (ExportedSerializableLog) is.readObject();
+				nextSerializableLog++;
+			} else {
+				XStream xstream = new XStream(new StaticReflectionProvider());
+				Object o = xstream.fromXML(new File(logFiles[nextLog]));
+				nextLog++;
+			}
 		} catch (Exception exi) {
 			exi.printStackTrace();
 		}
 	}
-
+
 	public static void main(String[] args) {
 		if (args.length < 2) {
 			System.err.println("Usage: ReplayRunner <mainClass> log [log2...logN] class_args [arg1...argM]");
@@ -49,19 +62,29 @@ public class ReplayRunner {
 		}
 		String mainClass = args[0];
 		logFiles = new String[args.length - 1];
+		serializableLogFiles = new String[args.length - 1];
 		int class_args = args.length;
+		int nLogs = 0;
+		int nSerializableLogs = 0;
+
 		for (int i = 1; i < args.length; i++) {
 			if (!args[i].equals("class_args"))
-				logFiles[i - 1] = args[i];
+				if (args[i].contains("_serializable_")) {
+					serializableLogFiles[nSerializableLogs] = args[i];
+					nSerializableLogs++;
+				} else {
+					logFiles[nLogs] = args[i];
+					nLogs++;
+				}
 			else {
 				class_args = i + 1;
 				break;
 			}
 		}
-
-		System.out.println("Available logs: " + Arrays.deepToString(logFiles));
-		_loadNextLog();

+		System.out.println("Available logs: " + Arrays.deepToString(logFiles));
+		_loadNextLog(Type.getDescriptor(ExportedLog.class));
+		_loadNextLog(Type.getDescriptor(ExportedSerializableLog.class));
 		Class<?> toRun;
 		try {
 			toRun = Class.forName(mainClass);
@@ -69,7 +92,7 @@ public class ReplayRunner {
 			String[] params = new String[args.length - class_args];
 			if (class_args < args.length)
 				System.arraycopy(args, class_args, params, 0, params.length);
-		    meth.invoke(null, new Object[]{ params });
+			meth.invoke(null, new Object[] { params });
 		} catch (ClassNotFoundException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();