[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: More on invokeGraphs



I forgot the attachment. Here it is.

Ankush

On Mon, 2 Dec 2002, Ankush Varma wrote:

> On Wed, 27 Nov 2002, Ondrej Lhotak wrote:
> 
> > On Wed, Nov 27, 2002 at 06:11:16PM -0500, Ankush Varma wrote:
> > > - Calling InvokeGraphTrimmer using PAG gave an invokeGraph with no methods
> > >   connected to my main method. Funny, but its probably mea culpa, since I
> > >   suspect I'm not using it properly.
> > > 
> > > Let me know if you have any ideas. Do you have a code fragment that trims an
> > > InvokeGraph using PAG?
> > 
> > The correct way to use Spark to get trim an invoke graph is:
> > java -Xmx300m soot.Main -a --app --nooutput -p wjtp.Spark disabled:false,trimInvokeGraph:true Hello
> 
> I'm calling Soot from inside a java method, rather than from the command
> line. Calling SPARK still gives returns an invoke graph with no methods
> connected to the main method.
> 
> I just called:
> ---
>         SparkTransformer.v().internalTransform("wjtp.Spark",
>                 _getCustomSparkOptions()); 
> ---
> 
> 
> where  _getCustomSparkOptions() returns a HashMap with the default SPARK
> options, except that trimInvokeGraph is set to true.
> 
> The output of my program looked like:
> 
> ---
> Start.
> Set all classes as apps ...
> Initial Scene has 1369 classes.
> Build InvokeGraph ....
> IG has 12404 methods in 1226 classes.
> Main method reaches 4610 methods.
> [Spark] Invoke Graph in 0.0 seconds.
> [Spark] Pointer Assignment Graph in 11.4 seconds.
> [Spark] Type masks in 14.4 seconds.
> [Spark] Pointer Graph simplified in 0.3 seconds.
> [Spark] Propagation in 7.2 seconds.
> [Spark] Solution found in 7.6 seconds.
> Trimming invoke graph
> Done trimming invoke graph
> After SPARK, 12404 methods.
> Main method reaches 0 methods.
> ---
> 
> I've attached my Java file to this mail. I simulated --app by setting all
> classes in the Scene as application classes.
> 
> Can you tell me what's the correct procedure for calling SPARK
> analysis from within a program?
> 
> Thanks,
> Ankush
> 
> > Then you retrieve the invoke graph from the Scene with
> > Scene.v().getActiveInvokeGraph().
> > 
> > > The smallest I could get was 2000+ transitive targets for a class that called
> > > nothing but System.out.println(int). Over 5000 methods were in the invoke graph
> > > for just this test file! Any idea how to get fewer nodes in the invokeGraph? I
> > > suspect that the MethodCallGraph is involved.
> > 
> > When run with the 1.3.1 JDK library, the above gives a graph with 1485
> > methods for a Hello, World program (compared to 2973 with just CHA).
> > (For comparison: 
> > Spark with onFlyCallGraph:true option: 1223
> > Spark (default options):               1485
> > VTA:                                   1556
> > RTA:                                   1919
> > CHA:                                   2973
> > 
> > In Java, it is difficult to get this much lower. First of all, even a
> > "trivial" Hello, World program is not at all trivial: using
> > java -verbose:class Hello
> > lists 280 classes being loaded with who knows how many methods.
> > 
> > Another difficulty is that class initiliazer methods can be called at
> > any time the first time a class is used, so they are treated as possible
> > entry points. Many of these create objects, making large numbers of
> > methods reachable.
> > 
> > > PS: The SPARK analysis in the new Soot release looks pretty neat! 
> > 
> > I'd be interested in hearing about your experiences with it.
> > 
> > Ondrej
> > 
> > 
> 
> -------------------------------------------------
> Ankush Varma
> Ph.D. Student / Graduate Research Assistant
> DSP-CAD Research Group 
> Department of Electrical and Computer Engineering
> University of Maryland, College Park.
> 
> email:
> ankush@eng.umd.edu
> not_ankush@yahoo.com
> 
> Home: 301-439-0438           Office: 301-405-3089
> --------------------------------------------------
> 
> 

-------------------------------------------------
Ankush Varma
Ph.D. Student / Graduate Research Assistant
DSP-CAD Research Group 
Department of Electrical and Computer Engineering
University of Maryland, College Park.

email:
ankush@eng.umd.edu
not_ankush@yahoo.com

Home: 301-439-0438           Office: 301-405-3089
--------------------------------------------------
/* Class that uses the Soot Framework to find out which methods/classes
   are really needed for code generation.

 Copyright (c) 2002 The University of Maryland.  
 All rights reserved.
 Permission is hereby granted, without written agreement and without
 license or royalty fees, to use, copy, modify, and distribute this
 software and its documentation for any purpose, provided that the above
 copyright notice and the following two paragraphs appear in all copies
 of this software.

 IN NO EVENT SHALL THE UNIVERSITY OF MARYLAND BE LIABLE TO ANY PARTY
 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 THE UNIVERSITY OF MARYLAND HAS BEEN ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.

 THE UNIVERSITY OF MARYLAND SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 MARYLAND HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 ENHANCEMENTS, OR MODIFICATIONS.

@ProposedRating Red (<your email address>)
@AcceptedRating Red (ssb@eng.umd.edu)
*/

//package ptolemy.copernicus.c;

import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.Hierarchy;

import soot.jimple.toolkits.invoke.*;
import soot.jimple.spark.*;
import soot.jimple.spark.builder.*;
import soot.jimple.spark.pag.*;

import java.util.Iterator;
import java.util.List;
import java.util.HashSet;
import java.util.HashMap;

import java.io.*;

//////////////////////////////////////////////////////////////////////////
//// TreePruner
/**
Class that uses the Soot Framework to find out which methods/classes
are really needed for code generation.

@author Ankush Varma
@version $Id$
*/

public class TreePruner {

   
    ///////////////////////////////////////////////////////////////////
    ////                         public methods                    ////
    public static void main(String[] args) {
        Scene.v().setSootClassPath(java.lang.System.getProperty("java.class.path"));
        Scene.v().loadClassAndSupport("printInt");
        SootClass sootClass = Scene.v().getSootClass("printInt");
        getTree(sootClass);
    }
        
    public static void getTree(SootClass source) {
        InvokeGraph invokeGraph;
        Scene.v().setMainClass(source);
        source.setApplicationClass();
        SootMethod mainMethod = source.getMethodByName("main");

        System.out.println("Start.");
        System.out.println("Set all classes as apps ...");
        // First set all classes to application classes.
        Iterator classes = Scene.v().getClasses().iterator();
        while (classes.hasNext()) {
            SootClass sootClass = (SootClass)classes.next();
            sootClass.setApplicationClass();
        }
            
           
        // Build an InvokeGraph.
        System.out.println("Initial Scene has " 
                + Scene.v().getClasses().size() + " classes.");
        System.out.println("Build InvokeGraph .... ");
        invokeGraph = ClassHierarchyAnalysis.newInvokeGraph(true);        
        Scene.v().setActiveInvokeGraph(invokeGraph);
        
        Iterator methods = invokeGraph.getReachableMethods().iterator();
        HashSet requiredClasses = new HashSet();
        while (methods.hasNext()) {
            requiredClasses.add(((SootMethod)methods.next())
                    .getDeclaringClass());
        }
            
        System.out.println("IG has " 
                + invokeGraph.getReachableMethods().size()
                + " methods in "
                + requiredClasses.size()
                + " classes.");

        System.out.println("Main method reaches "
                + invokeGraph.getTransitiveTargetsOf(mainMethod).size()
                + " methods.");
        
        SparkTransformer.v().internalTransform("wjtp.Spark",
                _getCustomSparkOptions()); 
        

        invokeGraph = Scene.v().getActiveInvokeGraph();

        System.out.println("After SPARK, " 
            + invokeGraph.getReachableMethods().size()
            + " methods.");
        System.out.println("Main method reaches "
                + invokeGraph.getTransitiveTargetsOf(mainMethod).size()
                + " methods.");
        
    }
    
    ///////////////////////////////////////////////////////////////////
    ////                         public fields                     ////
    

    ///////////////////////////////////////////////////////////////////
    ////                         protected methods                 ////
    protected static HashMap _getCustomSparkOptions() {
        HashMap options = _getDefaultSparkOptions();
        
        options.put("trimInvokeGraph", "true");
        //options.put("VTA", "true");
        //options.put("RTA", "true");
        //options.put("onFlyCallGraph", "true");
        //options.put("ignoreBaseObjects", "true");
        //options.put("dumpHTML", "true");
        return options;
    }
    
    protected static HashMap _getDefaultSparkOptions() {
        HashMap options = new HashMap();

        options.put("verbose", "false");
        options.put("ignoreTypesEntirely", "false");
        options.put("forceGCs", "false");
        options.put("VTA", "false");
        options.put("RTA", "false");
        options.put("ignoreBaseObjects", "false");
        options.put("typesForSites", "false");
        options.put("mergeStringBuffer", "true");
        options.put("simulateNatives", "false");
        options.put("simpleEdgesBidirectional", "false");
        options.put("onFlyCallGraph", "false");
        options.put("parmsAsFields", "false");
        options.put("returnsAsFields", "false");
        options.put("simplifyOffline", "false");
        options.put("simplifySCCs", "false");
        options.put("ignoreTypesForSCCs", "false");
        options.put("propagator", "worklist");
        options.put("setImpl", "double");
        options.put("doubleSetOld", "hybrid");
        options.put("doubleSetNew", "hybrid");
        options.put("dumpHTML", "false");
        options.put("dumpPAG", "false");
        options.put("dumpSolution", "false");
        options.put("topoSort", "false");
        options.put("dumpTypes", "true");
        options.put("classMethodVar", "true");
        options.put("dumpAnswer", "false");
        options.put("trimInvokeGraph", "false");
        
        return options;                
    }
                

    ///////////////////////////////////////////////////////////////////

   ////                       protected fields                    ////


    ///////////////////////////////////////////////////////////////////
    ////                         private methods                   ////


    ///////////////////////////////////////////////////////////////////
    ////                         private fields                    ////

}