[Soot-list] How to use soot to do whole program optimizations on android applications?

Jeremy Bell bell.jeremy at gmail.com
Wed Jun 23 09:52:34 EDT 2010


Proguard serves my needs well enough except for one thing - it can't do
optimizations which require escape analysis (most importantly, it doesn't do
scalar replacement of temporary reference type instantiations). I was told
that Soot can do these sorts of optimizations.

So, my first question is: Is it true?
And, my second question is: Assuming scalar replacement optimizations based
on escape analysis would require whole program analysis, how do I get soot
to do whole program analysis on an android application, which does not have
a single entry point (the main function), but potentially multiple entry
points (Activities, Services, DataProviders, etc..)?

 In proguard, I specify a number of classes with the --keep option, and each
of those classes' methods becomes the base of a new call tree (or some
similar implementation). I'd like to do something similar in soot.

Here are the kind of transformations I'm looking for (see the comments next
to the original code). This represents the rough java equivalent of an
implicit conversion in scala. I've gone ahead and inlined WrapperClass's
extensionMethod in the client code.

public final class SourceType {

public final string value;
public SourceType(String value) { this.value = value; }

}

public final class WrapperClass {

public final SourceType source;
public WrapperClass(SourceType source) { this.source = source; }
//public final void extensionMethod() { System.out.println(source.value); }
// <-- this is inlined by proguard, then eliminated from the bytecode

}

// assuming this class's methods are kept with --keep
public final class ClientCode {

// both allocations can be eliminated
public static void clientCodeMethod() {

SourceType x = new SourceType("hello"); // this could be eliminated

WrapperClass y = new WrapperClass(x); // this also could be eliminated


// this is WrapperClass.extensionMethod, which is inlined in this case

System.out.println(y.source.value); // this should instead be:
System.out.println("hello")

}

// wrapper class allocation can be eliminated, but not the SourceType
allocation (which escapes)
public static SourceType clientCodeMethod2() {

SourceType x = new SourceType("hello"); // this can't be eliminated, because
x escapes

WrapperClass y = new WrapperClass(x); // but this can still be eliminated

System.out.println(y.source.value); // this should instead be:
System.out.println(x.value)

return x; // x, escaping

}

// neither can be eliminated, because the WrapperClass instance escapes,
// and takes the SourceType instance with it
public static WrapperType clientCodeMethod3() {

SourceType x = new SourceType("hello"); // this can't be eliminated, because
it escapes with y

WrapperClass y = new WrapperClass(x); // this can't be eliminated, because
it escapes.

System.out.println(y.source.value); // this can't be optimized any further

return y; // y escapes and takes x with it

}

}

Also, note that while the body of clientCodeMethod3 can't eliminate the
allocations itself, it is possible they may be eliminated at the calling
site for that method, if the clientCodeMethod3 method is inlined, and y
doesn't escape the calling site method. If this can be done everywhere
clientCodeMethod3 is called, then the method itself can be eliminated.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.cs.mcgill.ca/pipermail/soot-list/attachments/20100623/9147448d/attachment-0001.html 


More information about the Soot-list mailing list