1 vivien   1.1.2.1 // MethodHole.java, created Fri Jul 28 by vivien
  2 vivien   1.1.2.1 // Copyright (C) 2000 Frederic VIVIEN <vivien@lcs.mit.edu>
  3 vivien   1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 
  4 vivien   1.1.2.1 package harpoon.Analysis.PointerAnalysis;
  5 vivien   1.1.2.1 
  6 vivien   1.1.2.1 import java.util.Iterator;
  7 vivien   1.1.2.1 import java.util.Set;
  8 vivien   1.1.2.1 import java.util.HashSet;
  9 vivien   1.1.2.1 import java.util.Map;
 10 vivien   1.1.2.1 import harpoon.Util.DataStructs.Relation;
 11 vivien   1.1.2.1 import harpoon.Util.DataStructs.LightRelation;
 12 vivien   1.1.2.1 import harpoon.Util.DataStructs.LightMap;
 13 vivien   1.1.2.1 import java.util.List;
 14 vivien   1.1.2.1 import java.util.LinkedList;
 15 vivien   1.1.2.1 
 16 vivien   1.1.2.1 import harpoon.Util.Util;
 17 vivien   1.1.2.1 
 18 vivien   1.1.2.1 import harpoon.IR.Quads.CALL;
 19 vivien   1.1.2.1 import harpoon.ClassFile.HMethod;
 20 vivien   1.1.2.1 import harpoon.Analysis.MetaMethods.MetaMethod;
 21 vivien   1.1.2.1 
 22 vivien   1.1.2.1 /**
 23 vivien   1.1.2.1  * <code>MetHolSet</code> contains the information corresponding to
 24 vivien   1.1.2.1  * method holes in a Parallel Interaction Graph.
 25 vivien   1.1.2.1  * 
 26 vivien   1.1.2.1  * @author  Frederic VIVIEN <vivien@lcs.mit.edu>
 27 cananian 1.5      * @version $Id: MethodHole.java,v 1.5 2004/02/08 03:20:02 cananian Exp $ */
 28 salcianu 1.1.2.2 public class MethodHole implements java.io.Serializable {
 29 vivien   1.1.2.1     private static boolean DEBUG  = false;
 30 vivien   1.1.2.1     private static boolean DEBUG2  = false;
 31 vivien   1.1.2.1 
 32 vivien   1.1.2.1     /** The call site of the unanalyzed method. */
 33 vivien   1.1.2.1     private CALL call_site;
 34 vivien   1.1.2.1 
 35 vivien   1.1.2.1     /** History of call sites between the original skipped call site,
 36 vivien   1.1.2.1      * and the current method. */
 37 vivien   1.1.2.1     private LinkedList sites_history;
 38 vivien   1.1.2.1 
 39 vivien   1.1.2.1     /** The array of the meta methods that can be called at call site
 40 vivien   1.1.2.1         <code>call_site</code>. */
 41 vivien   1.1.2.1     private MetaMethod[] mms;
 42 vivien   1.1.2.1 
 43 vivien   1.1.2.1     /** Set of all the parameter nodes for the unanalyzed method. */
 44 vivien   1.1.2.1     private Set __arguments;
 45 vivien   1.1.2.1     private Set __parameters;
 46 vivien   1.1.2.1     private Set [] __ungroupedparameters;
 47 vivien   1.1.2.1     private PANode retNode;
 48 vivien   1.1.2.1     private PANode excNode;
 49 vivien   1.1.2.1 
 50 vivien   1.1.2.1     // The rank of this method hole in the method holes generated for
 51 vivien   1.1.2.1     // the same call site (in case of loop or recursion).
 52 vivien   1.1.2.1     private int number;
 53 vivien   1.1.2.1 
 54 vivien   1.1.2.1     // The depth at which this method hole was found
 55 vivien   1.1.2.1     private int deepness;
 56 vivien   1.1.2.1 
 57 vivien   1.1.2.1     // Variable which enables to track down a MethodHole during the
 58 vivien   1.1.2.1     // MethodHoles conversioon pahse of mapups...
 59 vivien   1.1.2.1     private int mapup;
 60 vivien   1.1.2.1     private int id;
 61 vivien   1.1.2.1     private static int mapUpId = -1;
 62 vivien   1.1.2.1     private int numero;
 63 vivien   1.1.2.1     private static int nmh = 0;
 64 vivien   1.1.2.1 
 65 vivien   1.1.2.1 
 66 vivien   1.1.2.1     /** Return a set containing all the possible parameters.
 67 vivien   1.1.2.1      */
 68 vivien   1.1.2.1     public Set parameters() {
 69 vivien   1.1.2.1         if (__parameters==null){
 70 vivien   1.1.2.1             __parameters = new HashSet();
 71 vivien   1.1.2.1             for(int i=0; i<__ungroupedparameters.length; i++)
 72 vivien   1.1.2.1                 __parameters.addAll(__ungroupedparameters[i]);
 73 vivien   1.1.2.1         }
 74 vivien   1.1.2.1         return __parameters;
 75 vivien   1.1.2.1     }
 76 vivien   1.1.2.1  
 77 vivien   1.1.2.1     /** Return a set containing all the possible parameters, and the
 78 vivien   1.1.2.1      * formal return and exception nodes.
 79 vivien   1.1.2.1      */
 80 vivien   1.1.2.1     public Set arguments() {
 81 vivien   1.1.2.1         if(__arguments==null){
 82 vivien   1.1.2.1             __arguments = new HashSet(parameters());
 83 vivien   1.1.2.1             if(ret()!=null)
 84 vivien   1.1.2.1                 __arguments.add(ret());
 85 vivien   1.1.2.1             if(exc()!=null)
 86 vivien   1.1.2.1                 __arguments.add(exc());
 87 vivien   1.1.2.1         }
 88 vivien   1.1.2.1         return __arguments;
 89 vivien   1.1.2.1     }
 90 vivien   1.1.2.1  
 91 vivien   1.1.2.1 
 92 vivien   1.1.2.1     /** Return an array of set of possible actual parameters, each set
 93 vivien   1.1.2.1      * corresponding to a formal parameter.
 94 vivien   1.1.2.1      */
 95 vivien   1.1.2.1     public Set [] ungroupedparameters() {
 96 vivien   1.1.2.1         return __ungroupedparameters;
 97 vivien   1.1.2.1     }
 98 vivien   1.1.2.1  
 99 vivien   1.1.2.1 
100 vivien   1.1.2.1 
101 vivien   1.1.2.1     /** Creates a <code>MethodHole</code>. 
102 vivien   1.1.2.1      */
103 vivien   1.1.2.1     public MethodHole(CALL q, Set params, MetaMethod[] maybecalled,
104 vivien   1.1.2.1                       Set [] ungroupedparams, PANode ret, PANode exc,
105 vivien   1.1.2.1                       int rk, int dpth) {
106 vivien   1.1.2.1         call_site = q;
107 vivien   1.1.2.1         mms = maybecalled;
108 vivien   1.1.2.1         __parameters = params;
109 vivien   1.1.2.1         __arguments = null;
110 vivien   1.1.2.1         __ungroupedparameters = ungroupedparams;
111 vivien   1.1.2.1         retNode  = ret;
112 vivien   1.1.2.1         excNode  = exc;
113 vivien   1.1.2.1         number   = rk;
114 vivien   1.1.2.1         deepness = dpth;
115 vivien   1.1.2.1         if(ODPointerAnalysis.ODA_precise){
116 vivien   1.1.2.1             sites_history = new LinkedList();
117 vivien   1.1.2.1             sites_history.add(new Integer(number));
118 vivien   1.1.2.1         }
119 vivien   1.1.2.1         else
120 vivien   1.1.2.1             sites_history = new LinkedList();
121 vivien   1.1.2.1         mapup = -1;
122 vivien   1.1.2.1         id    = -1;
123 vivien   1.1.2.1         numero = MethodHole.nmh++;
124 vivien   1.1.2.1     }
125 vivien   1.1.2.1 
126 vivien   1.1.2.1 
127 vivien   1.1.2.1 
128 vivien   1.1.2.1     /** Creates a <code>MethodHole</code> which is a copy of the one
129 vivien   1.1.2.1      * given as argument, except for the parameters.
130 vivien   1.1.2.1      */
131 vivien   1.1.2.1     public MethodHole(MethodHole ref, Set [] ungroupedparams){
132 vivien   1.1.2.1         call_site = ref.callsite();
133 vivien   1.1.2.1         mms = ref.callees();
134 vivien   1.1.2.1         __ungroupedparameters = ungroupedparams;
135 vivien   1.1.2.1         __parameters = null;
136 vivien   1.1.2.1         __arguments  = null;
137 vivien   1.1.2.1         retNode  = ref.ret();
138 vivien   1.1.2.1         excNode  = ref.exc();
139 vivien   1.1.2.1         number   = ref.rank();
140 vivien   1.1.2.1         deepness = ref.depth();
141 vivien   1.1.2.1         sites_history = new LinkedList(ref.callsitehistory());
142 vivien   1.1.2.1         mapup = -1;
143 vivien   1.1.2.1         id    = -1;
144 vivien   1.1.2.1         numero = MethodHole.nmh++;
145 vivien   1.1.2.1     }
146 vivien   1.1.2.1 
147 vivien   1.1.2.1 
148 vivien   1.1.2.1     /** Creates a <code>MethodHole</code> which is a copy of the one
149 vivien   1.1.2.1      * given as argument, except that the parameters are mapped using
150 vivien   1.1.2.1      * the second argument.
151 vivien   1.1.2.1      */
152 vivien   1.1.2.1     public MethodHole(MethodHole ref, Map nodemap){
153 vivien   1.1.2.1         call_site = ref.callsite();
154 vivien   1.1.2.1         mms = ref.callees();
155 vivien   1.1.2.1         retNode  = ref.ret();
156 vivien   1.1.2.1         excNode  = ref.exc();
157 vivien   1.1.2.1         number   = ref.rank();
158 vivien   1.1.2.1         deepness = ref.depth();
159 vivien   1.1.2.1         sites_history = new LinkedList(ref.callsitehistory());
160 vivien   1.1.2.1 
161 vivien   1.1.2.1         __ungroupedparameters = new Set [ref.ungroupedparameters().length];
162 vivien   1.1.2.1         __parameters = null;
163 vivien   1.1.2.1         __arguments  = null;
164 vivien   1.1.2.1 
165 vivien   1.1.2.1         for(int i=0; i<ref.ungroupedparameters().length; i++){
166 vivien   1.1.2.1             __ungroupedparameters[i] = new HashSet();
167 vivien   1.1.2.1             Set params_i = ref.ungroupedparameters()[i];
168 vivien   1.1.2.1             if ((params_i!=null)&&(!(params_i.isEmpty())))
169 cananian 1.5                     for(Object nO : params_i){
170 cananian 1.5                         PANode n = (PANode) nO;
171 vivien   1.1.2.1                     PANode new_n = (PANode) nodemap.get(n);
172 vivien   1.1.2.1                     if (new_n==null) {
173 vivien   1.1.2.1                         System.err.println("Node with null translation: " + n);
174 vivien   1.1.2.1                         System.out.println("Node with null translation: " + n);
175 vivien   1.1.2.1                         System.out.println("in method hole " + ref);
176 vivien   1.1.2.1                         System.exit(1);
177 vivien   1.1.2.1                     }
178 vivien   1.1.2.1                     __ungroupedparameters[i].add(new_n);
179 vivien   1.1.2.1                 }
180 vivien   1.1.2.1         }
181 vivien   1.1.2.1         mapup = -1;
182 vivien   1.1.2.1         id    = -1;
183 vivien   1.1.2.1         numero = MethodHole.nmh++;
184 vivien   1.1.2.1     }
185 vivien   1.1.2.1 
186 vivien   1.1.2.1 
187 vivien   1.1.2.1     /** Creates a <code>MethodHole</code> which is a copy of the one
188 vivien   1.1.2.1      * given as argument, except for the parameters. 
189 vivien   1.1.2.1      */
190 vivien   1.1.2.1     public MethodHole(MethodHole ref, Set [] ungroupedparams, int incr, LinkedList ranks){
191 vivien   1.1.2.1         call_site = ref.callsite();
192 vivien   1.1.2.1         mms = ref.callees();
193 vivien   1.1.2.1         __ungroupedparameters = ungroupedparams;
194 vivien   1.1.2.1         __parameters = null;
195 vivien   1.1.2.1         __arguments  = null;
196 vivien   1.1.2.1         retNode  = ref.ret();
197 vivien   1.1.2.1         excNode  = ref.exc();
198 vivien   1.1.2.1         number   = ref.rank();
199 vivien   1.1.2.1         deepness = ref.depth()+incr;
200 vivien   1.1.2.1         sites_history = new LinkedList(ref.callsitehistory());
201 vivien   1.1.2.1         if (ranks!=null)
202 vivien   1.1.2.1             sites_history.addAll(ranks);
203 vivien   1.1.2.1         if ((ranks==null)&&(incr!=0)) {
204 vivien   1.1.2.1             System.err.println("Error in MethodHole creation...");
205 vivien   1.1.2.1             System.out.println("Error in MethodHole creation...");
206 vivien   1.1.2.1             System.out.println("incr = " + incr +",  CALL= " + ranks);
207 vivien   1.1.2.1             System.exit(1);
208 vivien   1.1.2.1         }
209 vivien   1.1.2.1         mapup = -1;
210 vivien   1.1.2.1         id    = -1;
211 vivien   1.1.2.1         numero = MethodHole.nmh++;
212 vivien   1.1.2.1     }
213 vivien   1.1.2.1 
214 vivien   1.1.2.1 
215 vivien   1.1.2.1     /** Return the <code>call site</code>. 
216 vivien   1.1.2.1      */
217 vivien   1.1.2.1     public CALL callsite(){
218 vivien   1.1.2.1         return call_site;
219 vivien   1.1.2.1     }
220 vivien   1.1.2.1 
221 vivien   1.1.2.1     /** Return the <code>history of call sites</code>. 
222 vivien   1.1.2.1      */
223 vivien   1.1.2.1     public LinkedList callsitehistory(){
224 vivien   1.1.2.1         return sites_history;
225 vivien   1.1.2.1     }
226 vivien   1.1.2.1 
227 vivien   1.1.2.1     /** Return the <code>rank</code>. 
228 vivien   1.1.2.1      */
229 vivien   1.1.2.1     public int rank(){
230 vivien   1.1.2.1         return number;
231 vivien   1.1.2.1     }
232 vivien   1.1.2.1 
233 vivien   1.1.2.1     /** Return the <code>depth</code>. 
234 vivien   1.1.2.1      */
235 vivien   1.1.2.1     public int depth(){
236 vivien   1.1.2.1         return deepness;
237 vivien   1.1.2.1     }
238 vivien   1.1.2.1 
239 vivien   1.1.2.1     /** Return the array of callees <code>MetaMethod</code>s. 
240 vivien   1.1.2.1      */
241 vivien   1.1.2.1     public MetaMethod[]  callees(){
242 vivien   1.1.2.1         return mms;
243 vivien   1.1.2.1     }
244 vivien   1.1.2.1 
245 vivien   1.1.2.1     /** Return the <code>HMethod</code> corresponding to the call site. 
246 vivien   1.1.2.1      */
247 vivien   1.1.2.1     public HMethod method(){
248 vivien   1.1.2.1         return call_site.method();
249 vivien   1.1.2.1     }
250 vivien   1.1.2.1 
251 vivien   1.1.2.1 
252 vivien   1.1.2.1     /** Return the result node. 
253 vivien   1.1.2.1      */
254 vivien   1.1.2.1     public PANode ret(){
255 vivien   1.1.2.1         return retNode;
256 vivien   1.1.2.1     }
257 vivien   1.1.2.1 
258 vivien   1.1.2.1 
259 vivien   1.1.2.1     /** Return the exception node. 
260 vivien   1.1.2.1      */
261 vivien   1.1.2.1     public PANode exc(){
262 vivien   1.1.2.1         return excNode;
263 vivien   1.1.2.1     }
264 vivien   1.1.2.1 
265 vivien   1.1.2.1 
266 vivien   1.1.2.1     /** Check whether <code>node</code> is a parameter node for the
267 vivien   1.1.2.1         unanalyzed method. 
268 vivien   1.1.2.1     */
269 vivien   1.1.2.1     public boolean contains(PANode node) {
270 vivien   1.1.2.1         for(int i=0; i<__ungroupedparameters.length; i++)
271 vivien   1.1.2.1             if(__ungroupedparameters[i].contains(node))  return true;
272 vivien   1.1.2.1         return false;
273 vivien   1.1.2.1     }
274 vivien   1.1.2.1 
275 vivien   1.1.2.1 
276 vivien   1.1.2.1     /** Check whether at least one of the <code>nodes</code> is a
277 vivien   1.1.2.1         parameter node for the unanalyzed method. 
278 vivien   1.1.2.1     */
279 vivien   1.1.2.1     public boolean containsnode(Set nodes) {
280 vivien   1.1.2.1         for(Iterator it=nodes.iterator(); it.hasNext(); )
281 vivien   1.1.2.1             if (contains((PANode)it.next()))
282 vivien   1.1.2.1                 return true;
283 vivien   1.1.2.1         return false;
284 vivien   1.1.2.1     }
285 vivien   1.1.2.1 
286 vivien   1.1.2.1 
287 vivien   1.1.2.1     /** Check whether <code>hm</code> is the method called at the
288 vivien   1.1.2.1         unanalyzed call site. 
289 vivien   1.1.2.1     */
290 vivien   1.1.2.1     public boolean contains(HMethod hm) {
291 vivien   1.1.2.1         return hm.equals(call_site.method());
292 vivien   1.1.2.1     }
293 vivien   1.1.2.1 
294 vivien   1.1.2.1 
295 vivien   1.1.2.1     /** Set the value of the field id. 
296 vivien   1.1.2.1      */
297 vivien   1.1.2.1     public void setId(int IntID){
298 vivien   1.1.2.1         id = IntID;
299 vivien   1.1.2.1     };
300 vivien   1.1.2.1 
301 vivien   1.1.2.1 
302 vivien   1.1.2.1     /** Read the value of the field id. 
303 vivien   1.1.2.1      */
304 vivien   1.1.2.1     public int Id() {
305 cananian 1.3.2.1         assert mapup==mapUpId : "Bad initialization value (not " +  
306 cananian 1.3.2.1                     mapUpId+ ") for MethodHole " + this;
307 vivien   1.1.2.1         return id;
308 vivien   1.1.2.1     };
309 vivien   1.1.2.1 
310 vivien   1.1.2.1 
311 vivien   1.1.2.1     /** Reset the global mapup flag, and the id and mapup fields of
312 vivien   1.1.2.1      * the <code>MethodHoles</code> given in argument.
313 vivien   1.1.2.1      */
314 vivien   1.1.2.1     public static void reset(Set holes1, Set holes2)
315 vivien   1.1.2.1     {
316 vivien   1.1.2.1         mapUpId++;
317 cananian 1.5             for(Object mhO : holes1){
318 cananian 1.5                 MethodHole mh = (MethodHole) mhO;
319 vivien   1.1.2.1             mh.id = -1;
320 vivien   1.1.2.1             mh.mapup = mapUpId;
321 vivien   1.1.2.1         }
322 cananian 1.5             for(Object mhO : holes2){
323 cananian 1.5                 MethodHole mh = (MethodHole) mhO;
324 vivien   1.1.2.1             mh.id    = -1;
325 vivien   1.1.2.1             mh.mapup = mapUpId;
326 vivien   1.1.2.1         }
327 vivien   1.1.2.1 
328 vivien   1.1.2.1         ODPointerAnalysis.BottomHole.id    = -1;
329 vivien   1.1.2.1         ODPointerAnalysis.BottomHole.mapup =  mapUpId;
330 vivien   1.1.2.1     }
331 vivien   1.1.2.1 
332 vivien   1.1.2.1 
333 vivien   1.1.2.1     /** Pretty-print function for debug purposes. 
334 vivien   1.1.2.1      */
335 vivien   1.1.2.1     public String toString(){
336 vivien   1.1.2.1         StringBuffer buffer = new StringBuffer();
337 vivien   1.1.2.1         buffer.append("MethodHole {");
338 vivien   1.1.2.1         buffer.append(" " + numero + " ");
339 vivien   1.1.2.1 
340 vivien   1.1.2.1         if (this==ODPointerAnalysis.BottomHole){
341 vivien   1.1.2.1             buffer.append(" ***bottom*** }");
342 vivien   1.1.2.1             return buffer.toString();
343 vivien   1.1.2.1         }
344 vivien   1.1.2.1 
345 vivien   1.1.2.1         buffer.append("Par [");
346 vivien   1.1.2.1         for(int i=0; i< __ungroupedparameters.length; i++){
347 cananian 1.5                 for(Object parO : (__ungroupedparameters[i])){
348 cananian 1.5                     PANode par = (PANode) parO;
349 vivien   1.1.2.1                 buffer.append(" " + par);               
350 vivien   1.1.2.1             }
351 vivien   1.1.2.1             if (i< __ungroupedparameters.length-1) buffer.append(";");
352 vivien   1.1.2.1         }
353 vivien   1.1.2.1         buffer.append("]; ");
354 vivien   1.1.2.1         buffer.append("Ret ["+retNode+"]; ");
355 vivien   1.1.2.1         buffer.append("Exc ["+excNode+"]; ");
356 vivien   1.1.2.1         buffer.append("Rank ["+rank()+"]; ");
357 vivien   1.1.2.1         buffer.append("Depth ["+depth()+"]; ");
358 vivien   1.1.2.1         buffer.append(sites_history);
359 vivien   1.1.2.1 
360 vivien   1.1.2.1         for(int i=0; i<mms.length; i++)
361 vivien   1.1.2.1             buffer.append(" " + mms[i]);
362 vivien   1.1.2.1 
363 vivien   1.1.2.1         if(DEBUG2)
364 vivien   1.1.2.1             {
365 vivien   1.1.2.1                 buffer.append(" Id " + id + " ");
366 vivien   1.1.2.1                 buffer.append("MapUp " + mapup + " ");
367 vivien   1.1.2.1             }
368 vivien   1.1.2.1         buffer.append("}");
369 vivien   1.1.2.1         
370 vivien   1.1.2.1 
371 vivien   1.1.2.1         return buffer.toString();
372 vivien   1.1.2.1     }
373 vivien   1.1.2.1 
374 vivien   1.1.2.1 
375 vivien   1.1.2.1     /** Clone a <code>MethodHole</code>.
376 vivien   1.1.2.1      */
377 vivien   1.1.2.1     public Object clone(){
378 vivien   1.1.2.1         return new MethodHole(this, ungroupedparameters());
379 vivien   1.1.2.1     }
380 vivien   1.1.2.1 
381 vivien   1.1.2.1 
382 vivien   1.1.2.1     /** Dummy function which creates a set of <code>MethodHole</code>
383 vivien   1.1.2.1      * which is a copy of the old one, while building an identity
384 vivien   1.1.2.1      * mapping other these <code>MethodHole</code>s.
385 vivien   1.1.2.1      */
386 vivien   1.1.2.1     public static Set DuplicateSet(Set org_holes, Map conversion)
387 vivien   1.1.2.1     {
388 vivien   1.1.2.1         HashSet new_holes = new HashSet();
389 vivien   1.1.2.1 
390 cananian 1.5             for(Object org_mhO : org_holes){
391 cananian 1.5                 MethodHole org_mh = (MethodHole) org_mhO;
392 vivien   1.1.2.1             if (org_mh!=null){
393 vivien   1.1.2.1                 conversion.put(org_mh, org_mh);
394 vivien   1.1.2.1                 new_holes.add(org_mh);
395 vivien   1.1.2.1             }
396 vivien   1.1.2.1             else{
397 vivien   1.1.2.1                 System.err.println("Hole is null!!!");
398 vivien   1.1.2.1                 System.out.println("Hole is null!!!");
399 vivien   1.1.2.1                 System.out.println(org_holes);
400 vivien   1.1.2.1                 System.exit(1);
401 vivien   1.1.2.1             }
402 vivien   1.1.2.1         }
403 vivien   1.1.2.1 
404 vivien   1.1.2.1         return new_holes;
405 vivien   1.1.2.1     }
406 vivien   1.1.2.1 
407 vivien   1.1.2.1     /** Create a new set of <code>MethodHole</code> from an old one
408 vivien   1.1.2.1      * and a <code>PANode</code> conversion table. This method outputs
409 vivien   1.1.2.1      * the new set and produces a conversion map from the old
410 vivien   1.1.2.1      * <code>MethodHole</code>s to the new ones.
411 vivien   1.1.2.1      */
412 vivien   1.1.2.1     public static Set DuplicateSet(Set org_holes, Map conversion, Map node_conversion)
413 vivien   1.1.2.1     {
414 vivien   1.1.2.1         HashSet new_holes = new HashSet();
415 vivien   1.1.2.1 
416 cananian 1.5             for(Object org_mhO : org_holes){
417 cananian 1.5                 MethodHole org_mh = (MethodHole) org_mhO;
418 vivien   1.1.2.1             if (org_mh!=null){
419 vivien   1.1.2.1                 MethodHole new_mh = null;
420 vivien   1.1.2.1                 new_mh = new MethodHole (org_mh, node_conversion);
421 vivien   1.1.2.1                 conversion.put(org_mh, new_mh);
422 vivien   1.1.2.1                 new_holes.add(new_mh);
423 vivien   1.1.2.1             }
424 vivien   1.1.2.1             else{
425 vivien   1.1.2.1                 System.err.println("Hole is null!!!");
426 vivien   1.1.2.1                 System.out.println("Hole is null!!!");
427 vivien   1.1.2.1                 System.out.println(org_holes);
428 vivien   1.1.2.1                 System.exit(1);
429 vivien   1.1.2.1             }
430 vivien   1.1.2.1         }
431 vivien   1.1.2.1         return new_holes;
432 vivien   1.1.2.1     }
433 vivien   1.1.2.1 
434 vivien   1.1.2.1 
435 vivien   1.1.2.1     /** Create a new <code>MethodHole</code> history relation from an
436 vivien   1.1.2.1      * old one and a <code>MethodHole</code> conversion map.
437 vivien   1.1.2.1      */
438 vivien   1.1.2.1     public static Relation DuplicateHistory(Relation org_hist, Map conversion)
439 vivien   1.1.2.1     {
440 vivien   1.1.2.1         LightRelation new_hist = new LightRelation();
441 vivien   1.1.2.1         
442 cananian 1.5             for(Object org_firstO : org_hist.keys()){
443 cananian 1.5                 MethodHole org_first = (MethodHole) org_firstO;
444 vivien   1.1.2.1             MethodHole new_first = (MethodHole) conversion.get(org_first);
445 vivien   1.1.2.1             if (new_first==null){
446 vivien   1.1.2.1                 System.err.println("DuplicateHistory: No conversion for " 
447 vivien   1.1.2.1                                    + org_first + "\n in "
448 vivien   1.1.2.1                                    + conversion +
449 vivien   1.1.2.1                                    "\n for " + org_hist);
450 vivien   1.1.2.1                 System.out.println("DuplicateHistory: No conversion for " 
451 vivien   1.1.2.1                                    + org_first + "\n in "
452 vivien   1.1.2.1                                    + conversion +
453 vivien   1.1.2.1                                    "\n for " + org_hist);
454 vivien   1.1.2.1                 System.exit(1);
455 vivien   1.1.2.1             }
456 vivien   1.1.2.1 
457 vivien   1.1.2.1             Set holes = new HashSet();
458 vivien   1.1.2.1             
459 cananian 1.5                 for(Object org_secondO : org_hist.getValues(org_first)){
460 vivien   1.1.2.1 
461 cananian 1.5                     MethodHole org_second = (MethodHole) org_secondO;
462 vivien   1.1.2.1                 MethodHole new_second = (MethodHole) conversion.get(org_second);
463 vivien   1.1.2.1                 if (new_second==null){
464 vivien   1.1.2.1                     System.err.println("DuplicateHistory (2): No conversion for " 
465 vivien   1.1.2.1                                        + org_second + "\n in "
466 vivien   1.1.2.1                                        + conversion + 
467 vivien   1.1.2.1                                        "\n for " + org_hist);
468 vivien   1.1.2.1                     System.out.println("DuplicateHistory (2): No conversion for " 
469 vivien   1.1.2.1                                        + org_second + "\n in "
470 vivien   1.1.2.1                                        + conversion + 
471 vivien   1.1.2.1                                        "\n for " + org_hist);
472 vivien   1.1.2.1                     System.exit(1);
473 vivien   1.1.2.1                 }
474 vivien   1.1.2.1                 holes.add(new_second);
475 vivien   1.1.2.1             }
476 vivien   1.1.2.1             new_hist.addAll(new_first,holes);
477 vivien   1.1.2.1         }
478 vivien   1.1.2.1         return new_hist;
479 vivien   1.1.2.1     }
480 vivien   1.1.2.1 
481 vivien   1.1.2.1 
482 vivien   1.1.2.1     /** Create a new lock relation from an old one and a
483 vivien   1.1.2.1      * <code>MethodHole</code> conversion map.
484 vivien   1.1.2.1      */
485 vivien   1.1.2.1     public static Relation DuplicateLocks(Relation org_locks, Map conversion)
486 vivien   1.1.2.1     {
487 vivien   1.1.2.1         LightRelation new_locks = new LightRelation();
488 vivien   1.1.2.1         
489 cananian 1.5             for(Object syncO : org_locks.keys()){
490 cananian 1.5                 PASync sync = (PASync) syncO;
491 vivien   1.1.2.1             Set new_holes = new HashSet();
492 cananian 1.5                 for(Object org_mhO : org_locks.getValues(sync))
493 vivien   1.1.2.1                 {
494 cananian 1.5                         MethodHole org_mh = (MethodHole) org_mhO;
495 vivien   1.1.2.1                     if (org_mh==null) {
496 vivien   1.1.2.1                         System.err.println("Null MethodHole in DuplicateLocks...");
497 vivien   1.1.2.1                         System.out.println("Null MethodHole in DuplicateLocks...");
498 vivien   1.1.2.1                         continue;
499 vivien   1.1.2.1                     }
500 vivien   1.1.2.1                     MethodHole new_mh = (MethodHole) conversion.get(org_mh);
501 vivien   1.1.2.1                     if (new_mh==null){
502 vivien   1.1.2.1                         System.err.println("DuplicateLocks: No conversion for " 
503 vivien   1.1.2.1                                            + org_mh + " in "
504 vivien   1.1.2.1                                            + conversion);
505 vivien   1.1.2.1                         System.out.println("DuplicateLocks: No conversion for " 
506 vivien   1.1.2.1                                            + org_mh + " in "
507 vivien   1.1.2.1                                            + conversion);
508 vivien   1.1.2.1                     }
509 vivien   1.1.2.1                     else{
510 vivien   1.1.2.1                         new_holes.add(new_mh);
511 vivien   1.1.2.1                     }
512 vivien   1.1.2.1                 }
513 vivien   1.1.2.1             new_locks.addAll(sync,new_holes);
514 vivien   1.1.2.1         }
515 vivien   1.1.2.1         return new_locks;
516 vivien   1.1.2.1     }
517 vivien   1.1.2.1 
518 vivien   1.1.2.1     /** Check whether the set of <code>MethodHole</code> contains a
519 vivien   1.1.2.1      * hole with the same content than the calling hole and, if this
520 vivien   1.1.2.1      * is the case, return such a copy.
521 vivien   1.1.2.1      */
522 vivien   1.1.2.1     public MethodHole IsInAs(Set holeset)
523 vivien   1.1.2.1     {
524 cananian 1.5             for(Object candidateO : holeset){
525 cananian 1.5                 MethodHole candidate = (MethodHole) candidateO;
526 vivien   1.1.2.1             if (strongEquals(candidate)) return candidate;
527 vivien   1.1.2.1         }
528 vivien   1.1.2.1         return null;
529 vivien   1.1.2.1     }
530 vivien   1.1.2.1 
531 vivien   1.1.2.1     /** Check whether the array of <code>MethodHole</code> contains a
532 vivien   1.1.2.1      * hole with the same content than the calling hole. In this case,
533 vivien   1.1.2.1      * the method returns the index of such a copy.
534 vivien   1.1.2.1      */
535 vivien   1.1.2.1     public int IsInAs(MethodHole[] holeArray, int size)
536 vivien   1.1.2.1     {
537 vivien   1.1.2.1         for(int i=0; i<size; i++)
538 vivien   1.1.2.1             if (strongEquals(holeArray[i])) return i;
539 vivien   1.1.2.1         return -1;
540 vivien   1.1.2.1     }
541 vivien   1.1.2.1 
542 vivien   1.1.2.1 
543 vivien   1.1.2.1     /** Check the equality of the content of two MethodHole, field by
544 vivien   1.1.2.1      * field. 
545 vivien   1.1.2.1      */
546 vivien   1.1.2.1     public boolean strongEquals(MethodHole mh)
547 vivien   1.1.2.1     {
548 vivien   1.1.2.1         if (rank() !=mh.rank()){
549 vivien   1.1.2.1             return false;
550 vivien   1.1.2.1         }
551 vivien   1.1.2.1         if (depth() !=mh.depth()){
552 vivien   1.1.2.1             return false;
553 vivien   1.1.2.1         }
554 vivien   1.1.2.1         if (callsite()!=mh.callsite()){
555 vivien   1.1.2.1             return false;
556 vivien   1.1.2.1         }
557 vivien   1.1.2.1         if (!(callsitehistory().equals(mh.callsitehistory()))){
558 vivien   1.1.2.1             return false;
559 vivien   1.1.2.1         }
560 vivien   1.1.2.1 
561 vivien   1.1.2.1         if (callees()!=mh.callees()){
562 vivien   1.1.2.1             return false;
563 vivien   1.1.2.1         }
564 vivien   1.1.2.1         if (ret() !=mh.ret()){
565 vivien   1.1.2.1             return false;
566 vivien   1.1.2.1         }
567 vivien   1.1.2.1         if (exc() !=mh.exc()){
568 vivien   1.1.2.1             return false;
569 vivien   1.1.2.1         }
570 vivien   1.1.2.1         if (ungroupedparameters().length !=mh.ungroupedparameters().length){
571 vivien   1.1.2.1             return false;
572 vivien   1.1.2.1         }
573 vivien   1.1.2.1         Set [] params_this = ungroupedparameters();
574 vivien   1.1.2.1         Set [] params_that = mh.ungroupedparameters();
575 vivien   1.1.2.1         for(int i=0; i<ungroupedparameters().length; i++){
576 vivien   1.1.2.1             if (!(params_this[i].containsAll(params_that[i]))){
577 vivien   1.1.2.1                 return false;
578 vivien   1.1.2.1             }
579 vivien   1.1.2.1             if (!(params_that[i].containsAll(params_this[i]))){
580 vivien   1.1.2.1                  return false;
581 vivien   1.1.2.1             }
582 vivien   1.1.2.1         }
583 vivien   1.1.2.1         
584 vivien   1.1.2.1         return true;
585 vivien   1.1.2.1     }
586 cananian 1.2     }