@Override
public void instructionExecuted(VM vm, ThreadInfo ti, Instruction nextInsn, Instruction executedInsn) {
-
// CASE #1: Detecting variable write-after-write conflict
if (executedInsn instanceof WriteInstruction) {
// Check for write-after-write conflict
}
private void checkWriteMapAndThrowError(String var, String value, String writer, ThreadInfo ti) {
-
+
if (writeMap.containsKey(var)) {
// Subsequent writes to the variable
VarChange current = writeMap.get(var);
// Find the variable writer
// It should be one of the apps listed in the .jpf file
private String getWriter(List<StackFrame> sfList) {
-
- for(StackFrame sf : sfList) {
- MethodInfo mi = sf.getMethodInfo();
+ // Start looking from the top of the stack backward
+ for(int i=sfList.size()-1; i>=0; i--) {
+ MethodInfo mi = sfList.get(i).getMethodInfo();
if(!mi.isJPFInternal()) {
String method = mi.getStackTraceName();
// Check against the apps in the appSet
for(String app : appSet) {
+ // There is only one writer at a time but we need to always
+ // check all the potential writers in the list
if (method.contains(app)) {
return app;
}
}
}
+ private String getName(ThreadInfo ti, Instruction inst, byte type) {
+ String name;
+ int index;
+ boolean store;
+
+ if ((inst instanceof JVMLocalVariableInstruction) ||
+ (inst instanceof JVMFieldInstruction)) {
+ name = ((LocalVariableInstruction) inst).getVariableId();
+ name = name.substring(name.lastIndexOf('.') + 1);
+
+ return(name);
+ }
+
+ if (inst instanceof JVMArrayElementInstruction) {
+ store = inst instanceof StoreInstruction;
+ name = getArrayName(ti, type, store);
+ index = getArrayIndex(ti, type, store);
+ return(name + '[' + index + ']');
+ }
+
+ return(null);
+ }
+
private String getValue(ThreadInfo ti, Instruction inst, byte type) {
StackFrame frame;
int lo, hi;
return(decodeValue(type, lo, hi));
}
+ if (inst instanceof JVMArrayElementInstruction)
+ return(getArrayValue(ti, type));
+
return(null);
}
+ private String getArrayName(ThreadInfo ti, byte type, boolean store) {
+ String attr;
+ int offset;
+
+ offset = calcOffset(type, store) + 1;
+ // <2do> String is really not a good attribute type to retrieve!
+ StackFrame frame = ti.getTopFrame();
+ attr = frame.getOperandAttr( offset, String.class);
+
+ if (attr != null) {
+ return(attr);
+ }
+
+ return("?");
+ }
+
+ private int getArrayIndex(ThreadInfo ti, byte type, boolean store) {
+ int offset;
+
+ offset = calcOffset(type, store);
+
+ return(ti.getTopFrame().peek(offset));
+ }
+
+ private final static int calcOffset(byte type, boolean store) {
+ if (!store)
+ return(0);
+
+ return(Types.getTypeSize(type));
+ }
+
+ private String getArrayValue(ThreadInfo ti, byte type) {
+ StackFrame frame;
+ int lo, hi;
+
+ frame = ti.getTopFrame();
+ lo = frame.peek();
+ hi = frame.getTopPos() >= 1 ? frame.peek(1) : 0;
+
+ return(decodeValue(type, lo, hi));
+ }
+
private final static String decodeValue(byte type, int lo, int hi) {
switch (type) {
case Types.T_ARRAY: return(null);