KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > callgraph > CallGraphBuilder


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2002 Ondrej Lhotak
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 package soot.jimple.toolkits.callgraph;
21 import soot.*;
22 import soot.options.*;
23 import soot.jimple.*;
24 import java.util.*;
25 import soot.util.*;
26 import soot.util.queue.*;
27
28 /** Models the call graph.
29  * @author Ondrej Lhotak
30  */

31 public final class CallGraphBuilder
32 {
33     private PointsToAnalysis pa;
34     private CGOptions options;
35     private ReachableMethods reachables;
36     private boolean appOnly = false;
37     private OnFlyCallGraphBuilder ofcgb;
38     private CallGraph cg;
39
40     public CallGraph getCallGraph() { return cg; }
41     public ReachableMethods reachables() { return reachables; }
42
43     public static ContextManager makeContextManager( CallGraph cg ) {
44         return new ContextInsensitiveContextManager( cg );
45     }
46
47     /** This constructor builds a complete call graph using the given
48      * PointsToAnalysis to resolve virtual calls. */

49     public CallGraphBuilder( PointsToAnalysis pa ) {
50         this.pa = pa;
51         options = new CGOptions( PhaseOptions.v().getPhaseOptions("cg") );
52         if( options.all_reachable() ) {
53             List entryPoints = new ArrayList();
54             entryPoints.addAll( EntryPoints.v().all() );
55             entryPoints.addAll( EntryPoints.v().methodsOfApplicationClasses() );
56             Scene.v().setEntryPoints( entryPoints );
57         }
58         cg = new CallGraph();
59         Scene.v().setCallGraph( cg );
60         reachables = Scene.v().getReachableMethods();
61         ContextManager cm = makeContextManager(cg);
62         ofcgb = new OnFlyCallGraphBuilder( cm, reachables );
63    }
64     /** This constructor builds the incomplete hack call graph for the
65      * Dava ThrowFinder.
66      * It uses all application class methods as entry points, and it ignores
67      * any calls by non-application class methods.
68      * Don't use this constructor if you need a real call graph. */

69     public CallGraphBuilder() {
70         G.v().out.println( "Warning: using incomplete callgraph containing "+
71                 "only application classes." );
72         pa = soot.jimple.toolkits.pointer.DumbPointerAnalysis.v();
73         options = new CGOptions( PhaseOptions.v().getPhaseOptions("cg") );
74         cg = new CallGraph();
75         Scene.v().setCallGraph(cg);
76         List entryPoints = new ArrayList();
77         entryPoints.addAll( EntryPoints.v().methodsOfApplicationClasses() );
78         entryPoints.addAll( EntryPoints.v().implicit() );
79         reachables = new ReachableMethods( cg, entryPoints );
80         appOnly = true;
81         ContextManager cm = new ContextInsensitiveContextManager( cg );
82         ofcgb = new OnFlyCallGraphBuilder( cm, reachables, true );
83     }
84     public void build() {
85         QueueReader worklist = reachables.listener();
86         while(true) {
87             ofcgb.processReachables();
88             reachables.update();
89             if( !worklist.hasNext() ) break;
90             MethodOrMethodContext momc = (MethodOrMethodContext) worklist.next();
91             List receivers = (List) ofcgb.methodToReceivers().get(momc.method());
92             if( receivers != null) for( Iterator receiverIt = receivers.iterator(); receiverIt.hasNext(); ) {
93                 final Local receiver = (Local) receiverIt.next();
94                 final PointsToSet p2set = pa.reachingObjects( receiver );
95                 for( Iterator typeIt = p2set.possibleTypes().iterator(); typeIt.hasNext(); ) {
96                     final Type type = (Type) typeIt.next();
97                     ofcgb.addType( receiver, momc.context(), type, null );
98                 }
99             }
100             List stringConstants = (List) ofcgb.methodToStringConstants().get(momc.method());
101             if( stringConstants != null ) for( Iterator stringConstantIt = stringConstants.iterator(); stringConstantIt.hasNext(); ) {
102                 final Local stringConstant = (Local) stringConstantIt.next();
103                 PointsToSet p2set = pa.reachingObjects( stringConstant );
104                 Collection possibleStringConstants = p2set.possibleStringConstants();
105                 if( possibleStringConstants == null ) {
106                     ofcgb.addStringConstant( stringConstant, momc.context(), null );
107                 } else {
108                     for( Iterator constantIt = possibleStringConstants.iterator(); constantIt.hasNext(); ) {
109                         final String JavaDoc constant = (String JavaDoc) constantIt.next();
110                         ofcgb.addStringConstant( stringConstant, momc.context(), constant );
111                     }
112                 }
113             }
114         }
115     }
116 }
117
118
Popular Tags