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:
parent
e788a94b06
commit
2750f8e67b
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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}));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user