I got Soot’s “may happen in parallel” (MHP) analysis to work, but only on a very small, completely unrealistic example which I used to test my “shared volatile” code (source below). Even for this, I needed to set the heap size to 2 GB (which, if I remember correctly, won’t work on Windows machines). Anything a little bit bigger either exhausted
memory or caused the JVM garbage collector crash.
They must be horribly inefficient with their static analysis. In one of the theses I read today, the biggest benchmarks had 3,800 lines of code. Maybe I am doing something wrong, because they used 1.5 GB heap, but as of now I have doubts their analysis scales to real applications like DrJava.
Furthermore, Soot’s MHP analysis doesn’t take the event thread into account, but this is probably a smaller issue.
package testers.volatileVarsThread;
public class VolatileVarsThread {
public static volatile int vsField;
public static int sField;
public static volatile int vsField_notShared;
public static int sField_notShared;
public static void main(String[] args) {
doStuff();
try {
new Thread(new Runnable() {
public void run() {
++vsField;
++sField;
System.out.println("Foo");
int i = doStuff() + doStuff();
System.out.println("i = "+i);
I c = new C();
c.doSomething();
}
}).start();
}
catch(java.lang.Exception e) { }
++vsField_notShared ;
++sField_notShared;
B b = new B();
b.doSomething();
}
public static int doStuff() {
return new A().foo() + 2;
}
}
class A {
public int foo() {
return bar() + 1;
}
public int bar() {
return 123;
}
}
interface I {
public void doSomething();
}
class B implements I {
public volatile int vField_notShared;
public int field_notShared;
public volatile int vField_notSharedButDynamicTarget;
public int field_notSharedButDynamicTarget;
public B() {
++vField_notShared;
++field_notShared;
}
public void doSomething() {
++vField_notSharedButDynamicTarget;
++field_notSharedButDynamicTarget;
System.out.println("B.doSomething");
}
}
class C implements I {
public volatile int vField = 3;
public int field = 4;
public void doSomething() {
vField = 0;
field = 0;
System.out.println("C.doSomething");
}
}