1) use less verbose instrumentation to reduce problems with methods

getting too big
2) handle issues with exceptional control flow not being followed
properly sometimes
This commit is contained in:
Julian Dolby 2014-01-07 17:35:44 -05:00
parent 1e2cc4bd6a
commit 1914f016dd
4 changed files with 56 additions and 62 deletions

View File

@ -1,17 +1,26 @@
package dynamicCG;
public class ExtraClass {
public ExtraClass() {
private final Object x;
public ExtraClass(Object x) {
this.x = x;
}
private static String getName() {
return "ExtraClass";
public ExtraClass() {
this(null);
}
private static String printObject() {
return " (object)";
}
private static String getName(Object x) {
return x.toString() + printObject();
}
@Override
public String toString() {
return getName();
return getName(x);
}
}

View File

@ -7,8 +7,20 @@ public class MainClass {
this.x = x;
}
private final String printNull() {
return "*null*";
}
private String callSomething(Object x) {
return "mc:" + (x==null? printNull(): x.toString());
}
private String toStringImpl() {
return "mc:" + x.toString();
try {
return "mc:" + x.toString();
} catch (NullPointerException e) {
return callSomething(x);
}
}
@Override
@ -17,7 +29,11 @@ public class MainClass {
}
public static void main(String[] args) {
MainClass mc = new MainClass(new ExtraClass());
MainClass mc = new MainClass(new ExtraClass("ExtraClass"));
System.err.println(mc.toString());
mc = new MainClass(null);
System.err.println(mc.toString());
mc = new MainClass(new ExtraClass());
System.err.println(mc.toString());
}
}

View File

@ -66,7 +66,12 @@ public class DynamicCallGraphTests extends WalaTestCase {
File tmpFile = TemporaryFile.urlToFile("exclusions.txt", getClass().getClassLoader().getResource(exclusionsFile));
System.setProperty("dynamicCGFilter", tmpFile.getCanonicalPath());
}
testMain.invoke(null, (Object)new String[0]);
try {
testMain.invoke(null, (Object)new String[0]);
} catch (Throwable e) {
// exceptions allowed here, just collecting CG
}
Assert.assertTrue("expected to create call graph", new File(System.getProperty("dynamicCGFile")).exists());
}
@ -101,7 +106,7 @@ public class DynamicCallGraphTests extends WalaTestCase {
Assert.assertEquals(1, nodes.size());
CGNode callee = nodes.iterator().next();
Assert.assertTrue(staticCG.getPossibleSites(caller, callee).hasNext());
Assert.assertTrue("no edge for " + caller + " --> " + callee, staticCG.getPossibleSites(caller, callee).hasNext());
System.err.println("found expected edge" + caller + " --> " + callee);
}

View File

@ -138,6 +138,22 @@ public class DynamicCallGraph {
}
});
me.addMethodExceptionHandler(null, new MethodEditor.Patch() {
@Override
public void emitTo(Output w) {
w.emit(ConstantInstruction.makeString(theClass));
w.emit(ConstantInstruction.makeString(theMethod));
//if (nonStatic)
// w.emit(LoadInstruction.make(Constants.TYPE_Object, 0)); //load this
//else
w.emit(Util.makeGet(runtime, "NULL_TAG"));
// w.emit(ConstantInstruction.make(Constants.TYPE_null, null));
w.emit(ConstantInstruction.make(1)); // true
w.emit(Util.makeInvoke(runtime, "termination", new Class[] {String.class, String.class, Object.class, boolean.class}));
w.emit(ThrowInstruction.make(false));
}
});
me.visitInstructions(new MethodEditor.Visitor() {
@Override
public void visitReturn(ReturnInstruction instruction) {
@ -156,58 +172,6 @@ public class DynamicCallGraph {
}
});
}
@Override
public void visitThrow(ThrowInstruction instruction) {
insertBefore(new MethodEditor.Patch() {
@Override
public void emitTo(Output w) {
w.emit(ConstantInstruction.makeString(theClass));
w.emit(ConstantInstruction.makeString(theMethod));
if (nonStatic)
w.emit(LoadInstruction.make(Constants.TYPE_Object, 0)); //load this
else
w.emit(Util.makeGet(runtime, "NULL_TAG"));
// w.emit(ConstantInstruction.make(Constants.TYPE_null, null));
w.emit(ConstantInstruction.make(1)); // true
w.emit(Util.makeInvoke(runtime, "termination", new Class[] {String.class, String.class, Object.class, boolean.class}));
}
});
}
@Override
public void visitInvoke(IInvokeInstruction inv) {
final String calleeClass = inv.getClassType();
final String calleeMethod = inv.getMethodName() + inv.getMethodSignature();
addInstructionExceptionHandler(/*"java.lang.Throwable"*/null, new MethodEditor.Patch() {
@Override
public void emitTo(MethodEditor.Output w) {
w.emit(ConstantInstruction.makeString(calleeClass));
w.emit(ConstantInstruction.makeString(calleeMethod));
w.emit(Util.makeInvoke(runtime, "pop", new Class[] {String.class, String.class}));
w.emit(ThrowInstruction.make(true));
}
});
insertBefore(new MethodEditor.Patch() {
@Override
public void emitTo(MethodEditor.Output w) {
w.emit(ConstantInstruction.makeString(calleeClass));
w.emit(ConstantInstruction.makeString(calleeMethod));
// target unknown
w.emit(Util.makeGet(runtime, "NULL_TAG"));
// w.emit(ConstantInstruction.make(Constants.TYPE_null, null));
w.emit(Util.makeInvoke(runtime, "addToCallStack", new Class[] {String.class, String.class, Object.class}));
}
});
insertAfter(new MethodEditor.Patch() {
@Override
public void emitTo(MethodEditor.Output w) {
w.emit(ConstantInstruction.makeString(calleeClass));
w.emit(ConstantInstruction.makeString(calleeMethod));
w.emit(Util.makeInvoke(runtime, "pop", new Class[] {String.class, String.class}));
}
});
}
});