[Soot-list] How can cancel other default optimization?

Jian Xu fightmyway at gmail.com
Wed Nov 12 21:31:18 EST 2008


Hi Eric:
*
For example, I construct the testing class A.*

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;



public class A {

    public static void main(String args[]){

        try {
            BufferedReader br = new BufferedReader(new FileReader("a.txt"));
            String line = br.readLine();
            while (line != null) {
                StringTokenizer st = new StringTokenizer(line);
                double x = Double.parseDouble(st.nextToken());
                double y = Double.parseDouble(st.nextToken());
                line = br.readLine();
            }
            br.close();
        } catch (IOException e) {
            System.out.println(e);
            System.exit(1);
        }
    }
}


*This is my Transform class. It's used to insert one probe in every A's
ExceptionalBlockGraph's block. In process, I print last unit of one block
with lineNumberTag.
*
package hku.instrument;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import soot.Body;
import soot.BodyTransformer;
import soot.Local;
import soot.PackManager;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.Transform;
import soot.Unit;
import soot.jimple.IdentityStmt;
import soot.jimple.IntConstant;
import soot.jimple.InvokeExpr;
import soot.jimple.InvokeStmt;
import soot.jimple.Jimple;
import soot.jimple.StringConstant;
import soot.options.Options;
import soot.toolkits.graph.Block;
import soot.toolkits.graph.ExceptionalBlockGraph;

public class Instrument {

    public static void main(String[] args) {
        Options.v().set_keep_line_number(true);
        PackManager.v().getPack("jap").add(
                new Transform("jap.instrumenter", StmtInstrument.v()));
        Scene.v().loadBasicClasses();
        Scene.v().addBasicClass("hku.profile.Counter",
SootClass.SIGNATURES);

        String ss[] = new String[]{ "A" };
        soot.Main.main(ss);
        System.out.println("Over --------- ");
    }


}

class StmtInstrument extends BodyTransformer {
    private static StmtInstrument instance = new StmtInstrument();
    private StmtInstrument() {
    }

    public static StmtInstrument v() {
        return instance;
    }


    static SootClass counterClass;
    static SootMethod increaseCounter, reportCounter;
    static {
        counterClass =
Scene.v().loadClassAndSupport("hku.instrument.Counter");
        increaseCounter = counterClass.getMethod("void
increase(java.lang.String,java.lang.String,int)");
    }


    @Override
    protected void internalTransform(Body b, String phaseName, Map options)
{
        // TODO Auto-generated method stub

        ExceptionalBlockGraph bGraph = new ExceptionalBlockGraph(b);

        Iterator<Block> blockIt = bGraph.getBlocks().iterator();
        Local counterLocal = Jimple.v().newLocal("counterRef",
                counterClass.getType());
        b.getLocals().add(counterLocal);
        String methodName = b.getMethod().toString();
        String className = methodName.substring(1, methodName.indexOf(":"));
        methodName = methodName.substring(methodName.indexOf(":")+2,
methodName.length()-1);

        while (blockIt.hasNext()) {
            Block block = (Block) blockIt.next();
            int blkIdx = block.getIndexInMethod();

            List args = new ArrayList();
            args.add(StringConstant.v(className));
            args.add(StringConstant.v(methodName));
            args.add(IntConstant.v(blkIdx));
            InvokeExpr incExpr = Jimple.v().newStaticInvokeExpr(
                    increaseCounter.makeRef(), args);
            InvokeStmt incStmt = Jimple.v().newInvokeStmt(incExpr);
            Unit uh = block.getTail();
            incStmt.addTag(uh.getTag("LineNumberTag"));

            if (uh instanceof IdentityStmt) {
                block.insertAfter(incStmt, uh);
            }else{
                block.insertBefore(incStmt, uh);
                uh.redirectJumpsToThisTo(incStmt);
            }

            System.out.print(uh.getTag("LineNumberTag")+": ");
            System.out.println(uh.toString()+"\n");

        }

    }
}

*The output is like this*
Soot started on Wed Nov 12 17:42:27 CST 2008
Transforming A...
10: return

15: r0 := @parameter0: java.lang.String[]

15: $r1 = new java.io.BufferedReader

15: $r2 = new java.io.FileReader

15: specialinvoke $r2.<java.io.FileReader: void
<init>(java.lang.String)>("a.txt")

15: specialinvoke $r1.<java.io.BufferedReader: void
<init>(java.io.Reader)>($r2)

15: r3 = $r1

16: r4 = virtualinvoke r3.<java.io.BufferedReader: java.lang.String
readLine()>()

17: goto [?= (branch)]

18: $r6 = new java.util.StringTokenizer

18: specialinvoke $r6.<java.util.StringTokenizer: void
<init>(java.lang.String)>(r4)

18: r5 = $r6

19: $r7 = virtualinvoke r5.<java.util.StringTokenizer: java.lang.String
nextToken()>()

19: staticinvoke <java.lang.Double: double
parseDouble(java.lang.String)>($r7)

20: $r8 = virtualinvoke r5.<java.util.StringTokenizer: java.lang.String
nextToken()>()

20: staticinvoke <java.lang.Double: double
parseDouble(java.lang.String)>($r8)

21: r4 = virtualinvoke r3.<java.io.BufferedReader: java.lang.String
readLine()>()

17: if r4 != null goto staticinvoke <hku.instrument.Counter: void
increase(java.lang.String,java.lang.String,int)>("xx.A", "void
main(java.lang.String[])", 8)

23: virtualinvoke r3.<java.io.BufferedReader: void close()>()

23: goto [?= return]

26: staticinvoke <java.lang.System: void exit(int)>(1)

28: return

Writing to sootOutput/srcbin/xx/A.class
Soot finished on Wed Nov 12 17:42:29 CST 2008
Soot has run for 0 min. 1 sec.
Over ---------


*Look at the line 18: r5 = $r6. when in instrument, it is a last line of one
block, actually the only unit in that block. But at last bytecode, if we
inpect the blocks of the exceptionalBlockGraph, this block is optimized
away. Because I insert my probe in this block, but other units has been
moved away, this probe is useless. So...*



On Wed, Nov 12, 2008 at 1:19 PM, Eric Bodden <eric.bodden at mail.mcgill.ca>wrote:

> Hmmm, I don't really know. What particular differences in the bytecode
> are you seeing?
>
> I think that there are some last-minute optimizations that Soot always
> runs, but it would help if you could give me some concrete examples so
> that I could try to determine what's actually going on.
>
> Eric
>
> 2008/11/11 Jian Xu <fightmyway at gmail.com>:
> > Hi Eric:
> > I find when I add my transformer to the "jap" pack, the target is still
> > moving on. The problem is about "unused local eliminate". this options
> can
> > disabled, but I wonder whether the other optimization will disturb the
> > bytecode?
> >
> > On Mon, Nov 10, 2008 at 10:49 PM, Eric Bodden <
> eric.bodden at mail.mcgill.ca>
> > wrote:
> >>
> >> Hi Jian.
> >>
> >> Yes, you are basically trying to shoot at a moving target, so it's
> >> best to not shoot until the target isn't moving any more ;-)
> >>
> >> Try adding your transformer to the "jap" pack instead:
> >>
> >>        PackManager.v().getPack("jap").add(
> >>                new Transform("jap.instrumenter", Mystrument.v()));
> >>
> >> The "jap" pack is executed after all optimizations and little to no
> >> transformations should take place after it.
> >>
> >> Maybe that's good enough in your case.
> >>
> >> Eric
> >>
> >> 2008/11/10 Jian Xu <fightmyway at gmail.com>:
> >> > Hi Eric:
> >> > Thank you for your reply.
> >> >
> >> > I do instrumentation, and insert instrument one instruction into every
> >> > ExceptionalBlockGraph's node --- Block.
> >> >         PackManager.v().getPack("jtp").add(
> >> >                 new Transform("jtp.instrumenter", Mystrument.v()));
> >> >         soot.Main.main();
> >> >
> >> > when I implement my Mystrument, soot read body which is a parameter of
> >> > "internalTransform(Body b, String phaseName, Map options)". I find the
> >> > body
> >> > is generated by javac and not have optimized. At last, soot create new
> >> > optimized bytecode. Of course, this is the power of soot. because I
> >> > insert
> >> > instruction into every Block, but at last the new bytecode optimized
> the
> >> > Block. The jimple code doesn't have any statement of that Block in the
> >> > original bytecode, except my instrument instruction. So this
> instrument
> >> > instruction is useless and strange.
> >> >
> >> > for example original code is
> >> > Block 0:
> >> > statement 1
> >> > statement 2
> >> >
> >> > Block 1:
> >> > statement 3
> >> >
> >> > Block 2:
> >> > statement 4
> >> >
> >> > then do instrumentation and I expect the code generated at last is
> >> > Block 0:
> >> > statement 1
> >> > statement 2
> >> > my instruction0
> >> >
> >> > Block 1:
> >> > statement 3
> >> > my instruction1
> >> >
> >> > Block 2:
> >> > statement 4
> >> > my instruction2
> >> >
> >> > but actually
> >> > Block 0:
> >> > statement 1
> >> > statement 2
> >> > my instruction0
> >> > my instruction1
> >> >
> >> > Block 1:
> >> > statement 4
> >> > my instruction2
> >> >
> >> > so all the Block index change. And the " my instruction1" in the
> actual
> >> > code
> >> > is useless. Is there a way to solve the problem?
> >> >
> >> > Now I reach my goal by changing the bytecode created by javac first
> >> > using
> >> > soot.
> >> > So the original code above is like:
> >> > Block 0:
> >> > statement 1
> >> > statement 2
> >> >
> >> > Block 1:
> >> > statement 4
> >> >
> >> > the new code
> >> > Block 0:
> >> > statement 1
> >> > statement 2
> >> > my instruction0
> >> >
> >> > Block 1:
> >> > statement 4
> >> > my instruction1
> >> >
> >> > Then every "my instruction " is useful. But you know when there are
> too
> >> > many
> >> > bytecodes, this way is time consuming.
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> > On Sun, Nov 9, 2008 at 10:25 PM, Eric Bodden
> >> > <eric.bodden at mail.mcgill.ca>
> >> > wrote:
> >> >>
> >> >> Hi Jian.
> >> >>
> >> >> This came up on the list just recently. See here:
> >> >>
> >> >>
> http://www.sable.mcgill.ca/pipermail/soot-list/2008-October/002012.html
> >> >>
> >> >> In a nutshell, you can disable most but not all optimizations, using
> >> >> phase options:
> >> >> http://www.sable.mcgill.ca/soot/tutorial/phase/index.html
> >> >>
> >> >>
> >> >> Eric
> >> >>
> >> >> 2008/11/9 Jian Xu <fightmyway at gmail.com>:
> >> >> > Hi:
> >> >> > I make instrument to bytecode, so I add my transfer object into
> "jtp"
> >> >> > pack
> >> >> > then call Soot.Main.main() in my main function. But I find the
> >> >> > bytecode
> >> >> > which generated by soot do more modification than my transfer
> object
> >> >> > do.
> >> >> > I
> >> >> > know when I call Soot.Main.main(), Soot do more optimization
> besides
> >> >> > what I
> >> >> > want to. So is there one way to do my transfer only but don't do
> >> >> > others?
> >> >> >
> >> >> > Regards
> >> >> > Jan
> >> >> >
> >> >> > _______________________________________________
> >> >> > Soot-list mailing list
> >> >> > Soot-list at sable.mcgill.ca
> >> >> > http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
> >> >> >
> >> >> >
> >> >>
> >> >>
> >> >>
> >> >> --
> >> >> Eric Bodden
> >> >> Sable Research Group, McGill University, Montréal, Canada
> >> >> Got an interesting job offer? http://www.bodden.de/hire-me/
> >> >
> >> >
> >>
> >>
> >>
> >> --
> >> Eric Bodden
> >> Sable Research Group, McGill University, Montréal, Canada
> >> Got an interesting job offer? http://www.bodden.de/hire-me/
> >
> >
>
>
>
> --
> Eric Bodden
> Sable Research Group, McGill University, Montréal, Canada
> Got an interesting job offer? http://www.bodden.de/hire-me/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.CS.McGill.CA/pipermail/soot-list/attachments/20081113/7aa26a79/attachment-0001.htm


More information about the Soot-list mailing list