KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > annotation > nullcheck > LocalRefVarsAnalysisWrapper


1 /*
2  * Copyright (C) 2000 Janus
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 /*
21
22      LocalRefVarsAnalysisWrapper class
23
24      Simple wrapper for BranchedRefVarsAnalysis, to be used by
25      the statement printer.
26
27      1) Compute lists of (ref, value) that have been analyzed:
28      * before a statement
29      * after a statement fall through
30      * after a statement branches
31
32      Note: (ref, kTop) are discareded to improve readability.
33      (This behavior can be turned off at compile time.)
34
35      
36      2) Compute lists of references that need to be checked by
37         a null pointer check at a given statement.
38
39         Compute lists of references that DO NOT need to be
40         checked by a null pointer check at a given statement.
41      
42     Notes:
43     a) that computation can be turned off at compile time
44     b) lists all references that (do not) need to be checked
45        not just the ones that have been analyzed.
46      
47 */

48
49
50 package soot.jimple.toolkits.annotation.nullcheck;
51
52 import soot.*;
53 import soot.toolkits.graph.*;
54 import soot.toolkits.scalar.*;
55 import java.util.*;
56
57 public class LocalRefVarsAnalysisWrapper
58 {
59     // compilation options
60
private static final boolean computeChecks = true;
61     private static final boolean discardKTop = true;
62
63     Map unitToVarsBefore;
64     Map unitToVarsAfterFall;
65     Map unitToListsOfVarsAfterBranches;
66     Map unitToVarsNeedCheck;
67     Map unitToVarsDontNeedCheck;
68     
69     BranchedRefVarsAnalysis analysis;
70
71     // utility method to build lists of (ref, value) pairs for a given flow set
72
// optionally discard (ref, kTop) pairs.
73
private final List buildList(FlowSet set)
74     {
75     List lst = new ArrayList();
76     Iterator it = analysis.refTypeValues.iterator();
77     while (it.hasNext()) {
78          EquivalentValue r = (EquivalentValue) it.next();
79         int refInfo = analysis.refInfo(r, set);
80         if (!(discardKTop && (refInfo == analysis.kTop)))
81         lst.add(analysis.getKRefIntPair(r, refInfo));
82         // remove tops from the list that will be printed for readability
83
}
84     return lst;
85     } // buildList
86

87
88     // constructor, where we do all our computations
89
public LocalRefVarsAnalysisWrapper(ExceptionalUnitGraph graph)
90     {
91         analysis = new BranchedRefVarsAnalysis(graph);
92         
93     unitToVarsBefore = new HashMap(graph.size() * 2 + 1, 0.7f);
94     unitToVarsAfterFall = new HashMap(graph.size() * 2 + 1, 0.7f);
95     unitToListsOfVarsAfterBranches = new HashMap(graph.size() * 2 + 1, 0.7f);
96     unitToVarsNeedCheck = new HashMap(graph.size() * 2 + 1, 0.7f);
97     unitToVarsDontNeedCheck = new HashMap(graph.size() * 2 + 1, 0.7f);
98     
99     Iterator unitIt = graph.iterator();
100     
101     while(unitIt.hasNext()) {
102         
103         FlowSet set;
104         Unit s = (Unit) unitIt.next();
105         
106         set = (FlowSet) analysis.getFallFlowAfter(s);
107         unitToVarsAfterFall.put(s, Collections.unmodifiableList(buildList(set)));
108         
109         // we get a list of flow sets for branches, iterate over them
110
{
111         List branchesFlowsets = analysis.getBranchFlowAfter(s);
112         List lst = new ArrayList(branchesFlowsets.size());
113         
114         Iterator it = branchesFlowsets.iterator();
115         while (it.hasNext()) {
116             set = (FlowSet) it.next();
117             lst.add(Collections.unmodifiableList(buildList(set)));
118         }
119         unitToListsOfVarsAfterBranches.put(s, lst);
120         } // done with branches
121

122         set = (FlowSet) analysis.getFlowBefore(s);
123         unitToVarsBefore.put(s, Collections.unmodifiableList(buildList(set)));
124         // NOTE: that set is used in the compute check bellow too
125

126         if (computeChecks) {
127
128         ArrayList dontNeedCheckVars = new ArrayList();
129         ArrayList needCheckVars = new ArrayList();
130         
131         HashSet allChecksSet = new HashSet(5, 0.7f);
132         allChecksSet.addAll((HashSet) analysis.unitToArrayRefChecksSet.get(s));
133         allChecksSet.addAll((HashSet) analysis.unitToInstanceFieldRefChecksSet.get(s));
134         allChecksSet.addAll((HashSet) analysis.unitToInstanceInvokeExprChecksSet.get(s));
135         allChecksSet.addAll((HashSet) analysis.unitToLengthExprChecksSet.get(s));
136         // set of all references that are subject to a null pointer check at this statement
137

138         Iterator it = allChecksSet.iterator();
139         
140         while (it.hasNext()) {
141
142             Value v = (Value) it.next();
143             int vInfo = analysis.anyRefInfo(v, set);
144
145             if (vInfo == analysis.kTop) {
146             // since it's a check, just print the name of the variable, we know it's top
147
needCheckVars.add(v);
148             } else if (vInfo == analysis.kBottom) {
149             // this could happen in some rare cases; cf known limitations
150
// in the BranchedRefVarsAnalysis implementation notes
151
needCheckVars.add(analysis.getKRefIntPair(new EquivalentValue(v), vInfo));
152             } else {
153             // no check, print the pair (ref, value), so we know why we are not doing the check
154
dontNeedCheckVars.add(analysis.getKRefIntPair(new EquivalentValue(v), vInfo));
155             }
156         }
157         
158         unitToVarsNeedCheck.put(s, Collections.unmodifiableList(needCheckVars));
159         unitToVarsDontNeedCheck.put(s, Collections.unmodifiableList(dontNeedCheckVars));
160         } // end if computeChecks
161

162     } // end while
163

164     } // end constructor & computations
165

166     
167     /*
168
169         Accesor methods.
170
171     Public accessor methods to the various class fields containing the results
172     of the computations.
173
174      */

175
176
177     public List getVarsBefore(Unit s)
178     {
179     return (List) unitToVarsBefore.get(s);
180     } // end getVarsBefore
181

182
183     public List getVarsAfterFall(Unit s)
184     {
185     return (List) unitToVarsAfterFall.get(s);
186     } // end getVarsAfterFall
187

188
189     public List getListsOfVarsAfterBranch(Unit s)
190     {
191     return (List) unitToListsOfVarsAfterBranches.get(s);
192     } // end getListsOfVarsAfterBranch
193

194     public List getVarsNeedCheck(Unit s)
195     {
196     if (computeChecks)
197         return (List) unitToVarsNeedCheck.get(s);
198     else
199         return new ArrayList();
200     } // end getVarsNeedCheck
201

202     public List getVarsDontNeedCheck(Unit s)
203     {
204     if (computeChecks)
205         return (List) unitToVarsDontNeedCheck.get(s);
206     else
207         return new ArrayList();
208     } // end getVarsNeedCheck
209

210
211 } // end class LocalRefVarsAnalysisWrapper
212
Popular Tags