1 salcianu 1.1 // PARTJSupportCompStage.java, created Tue Apr 22 16:24:48 2003 by salcianu
  2 salcianu 1.1 // Copyright (C) 2003 Alexandru Salcianu <salcianu@MIT.EDU>
  3 salcianu 1.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 salcianu 1.1 package harpoon.Analysis.PointerAnalysis;
  5 salcianu 1.1 
  6 salcianu 1.1 import harpoon.ClassFile.HClass;
  7 salcianu 1.1 import harpoon.ClassFile.NoSuchClassException;
  8 salcianu 1.1 import harpoon.ClassFile.HMethod;
  9 salcianu 1.1 import harpoon.ClassFile.HCode;
 10 salcianu 1.1 
 11 salcianu 1.1 import harpoon.Analysis.MetaMethods.MetaMethod;
 12 salcianu 1.1 
 13 salcianu 1.1 import harpoon.IR.Quads.Quad;
 14 salcianu 1.1 import harpoon.IR.Quads.CALL;
 15 salcianu 1.1 
 16 salcianu 1.1 import harpoon.Util.TypeInference.TypeInference;
 17 salcianu 1.1 import harpoon.Util.TypeInference.ExactTemp;
 18 salcianu 1.1 
 19 salcianu 1.1 import harpoon.Main.CompilerStage;
 20 salcianu 1.1 import harpoon.Main.CompilerStageEZ;
 21 salcianu 1.1 import harpoon.Main.CompStagePipeline;
 22 salcianu 1.1 import harpoon.Util.Options.Option;
 23 salcianu 1.1 
 24 salcianu 1.1 import harpoon.Util.Util;
 25 salcianu 1.1 
 26 salcianu 1.1 import java.util.List;
 27 salcianu 1.1 import java.util.LinkedList;
 28 salcianu 1.1 import java.util.Set;
 29 salcianu 1.1 import java.util.HashSet;
 30 salcianu 1.1 import java.util.Iterator;
 31 salcianu 1.1 import java.util.Collections;
 32 salcianu 1.1 
 33 salcianu 1.1 import java.io.IOException;
 34 salcianu 1.1 import java.io.BufferedReader;
 35 salcianu 1.1 import java.io.InputStreamReader;
 36 salcianu 1.1 
 37 salcianu 1.1 /**
 38 salcianu 1.1  * <code>PARTJSupportCompStage</code>
 39 salcianu 1.1  * 
 40 salcianu 1.1  * @author  Alexandru Salcianu <salcianu@MIT.EDU>
 41 cananian 1.2  * @version $Id: PARTJSupportCompStage.java,v 1.2 2004/02/08 03:20:03 cananian Exp $
 42 salcianu 1.1  */
 43 salcianu 1.1 public class PARTJSupportCompStage extends CompilerStageEZ {
 44 salcianu 1.1     
 45 salcianu 1.1     /** Creates a <code>PARTJSupportCompStage</code>. */
 46 salcianu 1.1     public PARTJSupportCompStage() { super("pa-4-rtj"); }
 47 salcianu 1.1 
 48 salcianu 1.1     /** Returns a compiler stage consisting of the sequential
 49 salcianu 1.1         composition of a pointer analysis stage and a
 50 salcianu 1.1         <code>PARTJSupportCompStage</code>. */
 51 salcianu 1.1     public static CompilerStage getFullStage() {
 52 salcianu 1.1         final CompilerStage rtjSupp = new PARTJSupportCompStage();
 53 salcianu 1.1         return 
 54 salcianu 1.1             new CompStagePipeline(new PointerAnalysisCompStage(true),
 55 salcianu 1.1                                   rtjSupp) {
 56 salcianu 1.1             public boolean enabled() { return rtjSupp.enabled(); }
 57 salcianu 1.1         };
 58 salcianu 1.1     }
 59 salcianu 1.1 
 60 salcianu 1.1 
 61 salcianu 1.1     // activates support for RTJ debug
 62 salcianu 1.1     private boolean RTJ_DEBUG = false;
 63 salcianu 1.1 
 64 salcianu 1.1     // keep all the rtj related memory assignments checks
 65 salcianu 1.1     private final static int RTJ_CR_KEEP_ALL_CHECKS   = 0;
 66 salcianu 1.1     // use the inter-proc analysis for check removal
 67 salcianu 1.1     private final static int RTJ_CR_INTER_PROC   = 1;
 68 salcianu 1.1     // use the inter-thread analysis for check removal
 69 salcianu 1.1     private final static int RTJ_CR_INTER_THREAD = 2;
 70 salcianu 1.1     // policy for RTJ check removal: should be one of the previous three
 71 salcianu 1.1     private int RTJ_CR_POLICY = RTJ_CR_KEEP_ALL_CHECKS;
 72 salcianu 1.1 
 73 salcianu 1.1     // examine all run() methods
 74 salcianu 1.1     private final static int RTJ_RI_ALL_RUNS = 0;
 75 salcianu 1.1     // examine only the run() methods belonging to classes that are
 76 salcianu 1.1     // passed as arguments to MemoryArea.enter()
 77 salcianu 1.1     private final static int RTJ_RI_ENTER    = 1;
 78 salcianu 1.1     // policy for identifying the relevant run() methods
 79 salcianu 1.1     private int RTJ_RI_POLICY = RTJ_RI_ENTER;
 80 salcianu 1.1 
 81 salcianu 1.1 
 82 salcianu 1.1     public List/*<Option>*/ getOptions() {
 83 salcianu 1.1         List/*<Option>*/ opts = new LinkedList/*<Option>*/();
 84 salcianu 1.1         opts.add(new Option("rtj-debug", "RTJ debug (interactive method inspecyion), with the help of Pointer Analysis") {
 85 salcianu 1.1             public void action() { RTJ_DEBUG = true; }
 86 salcianu 1.1         });
 87 salcianu 1.1 
 88 salcianu 1.1         opts.add(new Option("rtj-check-removal", "", "<runs> wit", "Try to use Pointer Analysis to remove all RTJ memory checks.  Optional argument <runs> = {allruns,enter} and tells how the relevant run methods are identified (default is enter).  If the optional argument \"wit\" is present, then use inter-thread analysis (by default, just inter-procedural pointer analysis") {
 89 salcianu 1.1             public void action() {
 90 salcianu 1.1                 RTJ_CR_POLICY = RTJ_CR_INTER_PROC;
 91 salcianu 1.1     
 92 salcianu 1.1                 if(getOptionalArg(0) != null) {
 93 salcianu 1.1                     String runs = getOptionalArg(0);
 94 salcianu 1.1                     if(runs.equals("allruns"))
 95 salcianu 1.1                         RTJ_RI_POLICY = RTJ_RI_ALL_RUNS;
 96 salcianu 1.1                     else if(runs.equals("enter"))
 97 salcianu 1.1                         RTJ_RI_POLICY = RTJ_RI_ENTER;
 98 salcianu 1.1                     else {
 99 salcianu 1.1                         System.err.println("Unknown <runs> options" + runs);
100 salcianu 1.1                         System.exit(1);
101 salcianu 1.1                     }
102 salcianu 1.1 
103 salcianu 1.1                     if(getOptionalArg(1) != null) {
104 salcianu 1.1                         if(getOptionalArg(1).equals("wit"))
105 salcianu 1.1                             RTJ_CR_POLICY = RTJ_CR_INTER_THREAD;
106 salcianu 1.1                         else {
107 salcianu 1.1                             System.err.println("Unknown optional arg" + 
108 salcianu 1.1                                                getOptionalArg(1));
109 salcianu 1.1                             System.exit(1);
110 salcianu 1.1                         }
111 salcianu 1.1                     }
112 salcianu 1.1                 }
113 salcianu 1.1             }
114 salcianu 1.1         });
115 salcianu 1.1         return opts;
116 salcianu 1.1     }
117 salcianu 1.1 
118 salcianu 1.1 
119 salcianu 1.1     public boolean enabled() {
120 salcianu 1.1         return 
121 salcianu 1.1             RTJ_DEBUG || (RTJ_CR_POLICY != RTJ_CR_KEEP_ALL_CHECKS);         
122 salcianu 1.1     }
123 salcianu 1.1 
124 salcianu 1.1 
125 salcianu 1.1     public void real_action() {
126 salcianu 1.1         pa = (PointerAnalysis) attribs.get("PointerAnalysis");
127 salcianu 1.1         assert pa != null : "No PointerAnalysis object";
128 salcianu 1.1 
129 salcianu 1.1         if(RTJ_DEBUG) {
130 salcianu 1.1             do_rtj_debug();
131 salcianu 1.1             System.exit(0);
132 salcianu 1.1         }
133 salcianu 1.1 
134 salcianu 1.1         switch(RTJ_CR_POLICY) {
135 salcianu 1.1         case RTJ_CR_KEEP_ALL_CHECKS:
136 salcianu 1.1             break;
137 salcianu 1.1         case RTJ_CR_INTER_PROC:
138 salcianu 1.1         case RTJ_CR_INTER_THREAD:
139 salcianu 1.1             java_lang_Runnable = linker.forName("java.lang.Runnable");
140 salcianu 1.1             if(can_remove_all_checks()) {
141 salcianu 1.1                 System.out.println("RTJ: can remove all checks!");
142 salcianu 1.1                 String rtj_options = "all";
143 salcianu 1.1                 // TODO: let the RTJ stage know that it may remove
144 salcianu 1.1                 // all memory checks!
145 salcianu 1.1             }
146 salcianu 1.1             else
147 salcianu 1.1                 System.out.println("RTJ: cannot remove all checks!");
148 salcianu 1.1             java_lang_Runnable = null;
149 salcianu 1.1             break;
150 salcianu 1.1         default:
151 salcianu 1.1             System.err.println("Unknown RTJ_CR_POLICY " + RTJ_CR_POLICY);
152 salcianu 1.1             System.exit(1);
153 salcianu 1.1         }
154 salcianu 1.1     }
155 salcianu 1.1 
156 salcianu 1.1     private PointerAnalysis pa = null;
157 salcianu 1.1     private HClass java_lang_Runnable = null;
158 salcianu 1.1 
159 salcianu 1.1 
160 salcianu 1.1     //////////////////////////////////////////////////////////////////////
161 salcianu 1.1     /////////////////////// RTJ DEBUG STUFF STARTS ///////////////////////
162 salcianu 1.1 
163 salcianu 1.1     private void do_rtj_debug() {
164 salcianu 1.1         BufferedReader d = 
165 salcianu 1.1             new BufferedReader(new InputStreamReader(System.in));
166 salcianu 1.1         System.out.println("\nRTJ interactive method inspection\n");
167 salcianu 1.1 
168 salcianu 1.1         while(true) {
169 salcianu 1.1             System.out.print("Method name:");
170 salcianu 1.1 
171 salcianu 1.1             String method = null;
172 salcianu 1.1             try {
173 salcianu 1.1                 method = d.readLine();
174 salcianu 1.1             } catch(IOException e) {
175 salcianu 1.1                 System.err.println("Error reading from System.in " + e);
176 salcianu 1.1                 e.printStackTrace();
177 salcianu 1.1                 System.exit(1);
178 salcianu 1.1             }
179 salcianu 1.1 
180 salcianu 1.1             if(method == null) { // EOF received
181 salcianu 1.1                 System.out.println();
182 salcianu 1.1                 break;
183 salcianu 1.1             }
184 salcianu 1.1 
185 salcianu 1.1             rtj_inspect_method(method);
186 salcianu 1.1         }
187 salcianu 1.1     }
188 salcianu 1.1 
189 salcianu 1.1 
190 salcianu 1.1     private void rtj_inspect_method(String method) {
191 salcianu 1.1         int point_pos = method.lastIndexOf('.');
192 salcianu 1.1         String declClassName = 
193 salcianu 1.1             (point_pos != -1) ?
194 salcianu 1.1             method.substring(0, point_pos) :
195 salcianu 1.1             // by default, same class as root method
196 salcianu 1.1             mainM.getDeclaringClass().getName();
197 salcianu 1.1         String methodName    = method.substring(point_pos + 1);
198 salcianu 1.1 
199 salcianu 1.1         HClass hclass = null;
200 salcianu 1.1         try {
201 salcianu 1.1             hclass = linker.forName(declClassName);
202 salcianu 1.1         } catch (NoSuchClassException e) {
203 salcianu 1.1             System.err.println("Class " + declClassName + " not found!");
204 salcianu 1.1             return;
205 salcianu 1.1         }
206 salcianu 1.1 
207 salcianu 1.1         HMethod[] hm  = hclass.getDeclaredMethods();
208 salcianu 1.1         HMethod hmethod = null;         
209 salcianu 1.1         for(int i = 0; i < hm.length; i++) {
210 salcianu 1.1             if(!hm[i].getName().equals(methodName)) continue;
211 salcianu 1.1 
212 salcianu 1.1             hmethod = hm[i];
213 salcianu 1.1             MetaMethod mm = hm2mm(hmethod);
214 salcianu 1.1 
215 salcianu 1.1             ParIntGraph ext_pig = pa.getExtParIntGraph(mm);
216 salcianu 1.1             System.out.println("METHOD " + hmethod);
217 salcianu 1.1             display_pointer_parameters(hmethod, pa);
218 salcianu 1.1             System.out.print("EXT. GRAPH AT THE END OF THE METHOD:");
219 salcianu 1.1             System.out.println(ext_pig);
220 salcianu 1.1             
221 salcianu 1.1             Set/*<PANode>*/ esc_nodes = ext_pig.allNodes();
222 salcianu 1.1             Set/*<PANode>*/ esc_inside_nodes = new HashSet/*<PANode>*/();
223 salcianu 1.1             
224 salcianu 1.1             // if one of the elements of the set nodes is an INSIDE
225 salcianu 1.1             // node, some objects are leaking out of the memory scope.
226 cananian 1.2             for(Object nodeO : esc_nodes) {
227 cananian 1.2                 PANode node = (PANode) nodeO;
228 salcianu 1.1                 if((node.type == PANode.INSIDE) && not_exception(node))
229 salcianu 1.1                     esc_inside_nodes.add(node);
230 salcianu 1.1             }
231 salcianu 1.1             
232 salcianu 1.1             if(esc_inside_nodes.isEmpty())
233 salcianu 1.1                 System.out.println("\tnothing escapes!");
234 salcianu 1.1             else
235 salcianu 1.1                 display_escaping_nodes(esc_inside_nodes);
236 salcianu 1.1         }
237 salcianu 1.1     
238 salcianu 1.1         if(hmethod == null)
239 salcianu 1.1             System.out.println(declClassName + "." + methodName +" not found");
240 salcianu 1.1     }
241 salcianu 1.1 
242 salcianu 1.1     
243 salcianu 1.1     private void display_escaping_nodes(Set/*<PANode>*/ nodes) {
244 salcianu 1.1         System.out.println("Escaping inside nodes:");
245 salcianu 1.1         for(Iterator/*<PANode>*/ it = nodes.iterator(); it.hasNext(); ) {
246 salcianu 1.1             PANode node = (PANode) it.next();
247 salcianu 1.1             System.out.println(" " + node);
248 salcianu 1.1             System.out.println
249 salcianu 1.1                 ("  CREATED IN: " + 
250 salcianu 1.1                  Util.code2str
251 salcianu 1.1                  (pa.getNodeRepository().node2Code(node.getRoot())));
252 salcianu 1.1         }
253 salcianu 1.1     }
254 salcianu 1.1 
255 salcianu 1.1     // displays the parameter nodes for method hm
256 salcianu 1.1     // TODO: print the sources of all the nodes that appear in displayed pigs.
257 salcianu 1.1     private void display_pointer_parameters(HMethod hm, PointerAnalysis pa) {
258 salcianu 1.1         PANode[] nodes = pa.getParamNodes(new MetaMethod(hm, true));
259 salcianu 1.1         System.out.print("POINTER PARAMETERS: ");
260 salcianu 1.1         System.out.print("[ ");
261 salcianu 1.1         for(int j = 0; j < nodes.length; j++)
262 salcianu 1.1             System.out.print(nodes[j] + " ");
263 salcianu 1.1         System.out.println("]");
264 salcianu 1.1     }
265 salcianu 1.1 
266 salcianu 1.1     // Checks whether node is an exception node or not.
267 salcianu 1.1     private boolean not_exception(PANode node) {
268 salcianu 1.1         System.out.println("not_excp: " + node);
269 salcianu 1.1 
270 salcianu 1.1         HClass hclass = pa.getNodeRepository().getInsideNodeType(node);
271 salcianu 1.1         if(java_lang_Throwable == null)
272 salcianu 1.1             java_lang_Throwable = linker.forName("java.lang.Throwable");
273 salcianu 1.1         return ! ( java_lang_Throwable.isSuperclassOf(hclass) ); 
274 salcianu 1.1     }
275 salcianu 1.1     private HClass java_lang_Throwable = null;
276 salcianu 1.1 
277 salcianu 1.1     /////////////////////// RTJ DEBUG STUFF ENDS /////////////////////////
278 salcianu 1.1     //////////////////////////////////////////////////////////////////////
279 salcianu 1.1     
280 salcianu 1.1 
281 salcianu 1.1 
282 salcianu 1.1     //////////////////////////////////////////////////////////////////////
283 salcianu 1.1     //////////////////// RTJ CHECK REMOVAL STARTS ////////////////////////
284 salcianu 1.1 
285 salcianu 1.1     private static boolean DEBUG_RT = true;
286 salcianu 1.1 
287 salcianu 1.1     private boolean can_remove_all_checks() {
288 salcianu 1.1         long start = time();
289 salcianu 1.1         boolean result = can_remove_all_checks2();
290 salcianu 1.1         System.out.println("RTJ: can_remove_all_checks ... " + 
291 salcianu 1.1                            (time() - start) + " ms");
292 salcianu 1.1         return result;
293 salcianu 1.1     }
294 salcianu 1.1 
295 salcianu 1.1     private boolean can_remove_all_checks2() {
296 cananian 1.2         for(Object hmO : get_relevant_runs()) {
297 cananian 1.2             HMethod hm = (HMethod) hmO;
298 salcianu 1.1             if(!nothing_escapes(hm))
299 salcianu 1.1                 return false;
300 salcianu 1.1         }
301 salcianu 1.1         return true;
302 salcianu 1.1     }
303 salcianu 1.1     
304 salcianu 1.1 
305 salcianu 1.1     private static MetaMethod hm2mm(HMethod hm) {
306 salcianu 1.1         return new MetaMethod(hm, true);
307 salcianu 1.1     }
308 salcianu 1.1 
309 salcianu 1.1     // Returns a set that contains all the run methods of all
310 salcianu 1.1     // the Runnable classes that might be passed as arguments to
311 salcianu 1.1     // javax.realtime.CTMemory.enter
312 salcianu 1.1     private Set/*<HMethod>*/ get_relevant_runs() {
313 salcianu 1.1         Set/*<HMethod>*/ result = Collections.EMPTY_SET;
314 salcianu 1.1 
315 salcianu 1.1         if(RTJ_RI_POLICY == RTJ_RI_ALL_RUNS)
316 salcianu 1.1             result = get_all_runs();
317 salcianu 1.1         else if(RTJ_RI_POLICY == RTJ_RI_ENTER)
318 salcianu 1.1             result = get_entered_runs();
319 salcianu 1.1         else
320 salcianu 1.1             assert false : "RTJ: Unknown run identification policy!";
321 salcianu 1.1         
322 salcianu 1.1         if(result.isEmpty())
323 salcianu 1.1             System.out.println("RTJ: WARNING: no run() was found!");
324 salcianu 1.1         else if(DEBUG_RT)
325 salcianu 1.1             Util.print_collection(result, "RTJ: run() methods", "RTJ: ");
326 salcianu 1.1 
327 salcianu 1.1         return result;
328 salcianu 1.1     }
329 salcianu 1.1 
330 salcianu 1.1 
331 salcianu 1.1     // Returns the set of all the run() methods of classes that implements
332 salcianu 1.1     // java.lang.Runnable
333 salcianu 1.1     private Set/*<HMethod>*/ get_all_runs() {
334 salcianu 1.1         Set/*<HMethod>*/ runs = new HashSet();
335 salcianu 1.1         for(Iterator/*<HClass>*/ it = 
336 salcianu 1.1                 classHierarchy.instantiatedClasses().iterator();
337 salcianu 1.1             it.hasNext(); ) {
338 salcianu 1.1             HMethod run = extract_run((HClass) it.next());
339 salcianu 1.1             if(run != null)
340 salcianu 1.1                 runs.add(run);
341 salcianu 1.1         }
342 salcianu 1.1         return runs;
343 salcianu 1.1     }
344 salcianu 1.1 
345 salcianu 1.1 
346 salcianu 1.1     /////////////////// get_entered_runs START ////////////////////////
347 salcianu 1.1 
348 salcianu 1.1     // Returns the set of run() methods of Runnable objects that are
349 salcianu 1.1     // passed to the enter method of some subclass of MemoryArea.
350 salcianu 1.1     private Set/*<HMethod>*/ get_entered_runs() {
351 salcianu 1.1         Set/*<HMethod>*/ result = new HashSet();
352 salcianu 1.1         Set/*<HMethod>*/ enters = get_enter_methods();
353 salcianu 1.1         for(Iterator/*<HMethod>*/ it = enters.iterator(); it.hasNext(); ) {
354 salcianu 1.1             HMethod enter = (HMethod) it.next();
355 salcianu 1.1 
356 salcianu 1.1             MetaMethod[] callers = 
357 salcianu 1.1                 pa.getMetaAllCallers().getCallers(hm2mm(enter));
358 salcianu 1.1 
359 salcianu 1.1             for(int i = 0; i < callers.length; i++)
360 salcianu 1.1                 result.addAll(get_entered_runs(callers[i].getHMethod(),enter));
361 salcianu 1.1         }
362 salcianu 1.1         return result;
363 salcianu 1.1     }
364 salcianu 1.1 
365 salcianu 1.1 
366 salcianu 1.1     // Returns the set of enter methods declared in subclasses of MemoryArea.
367 salcianu 1.1     private Set/*<HMethod>*/ get_enter_methods() {
368 salcianu 1.1         Set/*<HMethod>*/ enters = new HashSet/*<HMethod>*/();
369 salcianu 1.1 
370 salcianu 1.1         HClass javax_realtime_MemoryArea = 
371 salcianu 1.1             linker.forName("javax.realtime.MemoryArea");
372 salcianu 1.1         Set/*<HClass>*/ children = 
373 salcianu 1.1             classHierarchy.children(javax_realtime_MemoryArea);
374 salcianu 1.1 
375 salcianu 1.1         for(Iterator/*<HClass>*/ it = children.iterator(); it.hasNext(); ) {
376 salcianu 1.1             HClass hclass = (HClass) it.next();
377 salcianu 1.1             if(!classHierarchy.instantiatedClasses().contains(hclass))
378 salcianu 1.1                 it.remove();
379 salcianu 1.1         }
380 salcianu 1.1 
381 salcianu 1.1         if(DEBUG_RT)
382 salcianu 1.1             Util.print_collection
383 salcianu 1.1                 (children, "RTJ: Subclasses of javax.realtime.MemoryArea",
384 salcianu 1.1                  "RTJ: ");
385 salcianu 1.1 
386 cananian 1.2         for(Object hclassO : children) {
387 cananian 1.2             HClass hclass = (HClass) hclassO;
388 salcianu 1.1             HMethod[] hms = hclass.getMethods();
389 salcianu 1.1             for(int i = 0; i < hms.length; i++) {
390 salcianu 1.1                 if(hms[i].getName().equals("enter") &&
391 salcianu 1.1                    (hms[i].getParameterTypes().length == 1))
392 salcianu 1.1                     enters.add(hms[i]);
393 salcianu 1.1             }
394 salcianu 1.1         }
395 salcianu 1.1 
396 salcianu 1.1         if(DEBUG_RT)
397 salcianu 1.1             Util.print_collection(enters, "RTJ: enter() methods", "RTJ: ");
398 salcianu 1.1 
399 salcianu 1.1         return enters;
400 salcianu 1.1     }
401 salcianu 1.1 
402 salcianu 1.1 
403 salcianu 1.1     // Goes over all the calls to method enter inside the body of hm
404 salcianu 1.1     // and collect all the run methods that enter will implicitly call
405 salcianu 1.1     // (enter is supposed to be a javax.realtime.MemoryArea.enter style
406 salcianu 1.1     // method)
407 salcianu 1.1     private Set/*<HMethod>*/ get_entered_runs(HMethod hm, HMethod enter) {
408 salcianu 1.1         Set/*<HMethod>*/ result = new HashSet/*<HMethod>*/();
409 salcianu 1.1 
410 salcianu 1.1         if(DEBUG_RT)
411 salcianu 1.1             System.out.println("RTJ: get_interesting_runs(" + hm +
412 salcianu 1.1                                "," + enter + ") entered");
413 salcianu 1.1 
414 salcianu 1.1         Set/*<CALL>*/ calls = get_calls_to_enter(hm, enter);
415 salcianu 1.1         
416 salcianu 1.1         if(DEBUG_RT)
417 salcianu 1.1             Util.print_collection(calls, "Interesting calls ", "RTJ: ");
418 salcianu 1.1 
419 salcianu 1.1         TypeInference ti =
420 salcianu 1.1             new TypeInference(hm, hcf.convert(hm), get_ietemps(calls));
421 salcianu 1.1 
422 salcianu 1.1         for(Iterator/*<CALL>*/ it = calls.iterator(); it.hasNext(); ) {
423 salcianu 1.1             CALL cs = (CALL) it.next();
424 salcianu 1.1             ExactTemp et = new ExactTemp(cs, cs.params(1));
425 salcianu 1.1             Set types = ti.getType(et);
426 salcianu 1.1 
427 salcianu 1.1             if(DEBUG_RT)
428 salcianu 1.1                 Util.print_collection(types, "Possible types for "+et,"RTJ: ");
429 salcianu 1.1 
430 cananian 1.2             for(Object hclassO : types) {
431 cananian 1.2                 HClass hclass = (HClass) hclassO;               
432 salcianu 1.1                 Set children = new HashSet(classHierarchy.children(hclass));
433 salcianu 1.1 
434 salcianu 1.1                 children.add(hclass);
435 salcianu 1.1 
436 salcianu 1.1                 if(DEBUG_RT)
437 salcianu 1.1                     Util.print_collection(children, "Children for " + hclass,
438 salcianu 1.1                                           "RTJ: ");
439 salcianu 1.1 
440 cananian 1.2                 for(Object childO : children) {
441 cananian 1.2                     HClass child = (HClass) childO;
442 salcianu 1.1                     if(classHierarchy.instantiatedClasses().contains(child)) {
443 salcianu 1.1                         HMethod run = extract_run(child);
444 salcianu 1.1                         if(run != null)
445 salcianu 1.1                             result.add(run);
446 salcianu 1.1                     }
447 salcianu 1.1                 }
448 salcianu 1.1             }
449 salcianu 1.1         }
450 salcianu 1.1         return result;
451 salcianu 1.1     }
452 salcianu 1.1 
453 salcianu 1.1 
454 salcianu 1.1     // Returns the set of the CALLs to method "enter" inside the code of hm. 
455 salcianu 1.1     private Set/*<CALL>*/ get_calls_to_enter(HMethod hm, HMethod enter) {
456 salcianu 1.1         if(DEBUG_RT)
457 salcianu 1.1             System.out.println("RTJ: get_interesting_calls(" +
458 salcianu 1.1                                hm + "," + enter + ") entered");
459 salcianu 1.1 
460 salcianu 1.1         Set/*<CALL>*/ calls = new HashSet/*<CALL>*/();
461 salcianu 1.1         HCode hcode = hcf.convert(hm);
462 salcianu 1.1         for(Iterator it = hcode.getElementsI(); it.hasNext(); ) {
463 salcianu 1.1             Quad quad = (Quad) it.next();
464 salcianu 1.1             if(quad instanceof CALL) {
465 salcianu 1.1                 CALL cs = (CALL) quad;
466 salcianu 1.1                 MetaMethod[] callees = 
467 salcianu 1.1                     pa.getMetaCallGraph().getCallees(hm2mm(hm), cs);
468 salcianu 1.1                 for(int i = 0; i < callees.length; i++) {
469 salcianu 1.1                     if(callees[i].getHMethod().equals(enter)) {
470 salcianu 1.1                         calls.add(cs);
471 salcianu 1.1                         break;
472 salcianu 1.1                     }
473 salcianu 1.1                 }
474 salcianu 1.1             }
475 salcianu 1.1         }
476 salcianu 1.1         return calls;
477 salcianu 1.1     }
478 salcianu 1.1 
479 salcianu 1.1 
480 salcianu 1.1     // Given a class, verify that it's implementing java.lang.Runnable and
481 salcianu 1.1     // extract its run() method. Return null if the verification fails or
482 salcianu 1.1     // no run() method exists in hclass.
483 salcianu 1.1     private HMethod extract_run(HClass hclass) {
484 salcianu 1.1         if(!hclass.isInstanceOf(java_lang_Runnable))
485 salcianu 1.1             return null;
486 salcianu 1.1 
487 salcianu 1.1         if(DEBUG_RT)
488 salcianu 1.1             System.out.println("RTJ: extract_run(" + hclass + ") entered");
489 salcianu 1.1 
490 salcianu 1.1         HMethod[] hms = hclass.getMethods();
491 salcianu 1.1         for(int i = 0; i < hms.length; i++) {
492 salcianu 1.1             if(hms[i].getName().equals("run") &&
493 salcianu 1.1                (hms[i].getParameterTypes().length == 0)) {
494 salcianu 1.1                 
495 salcianu 1.1                 if(DEBUG_RT)
496 salcianu 1.1                     System.out.println("\t" + hms[i]);
497 salcianu 1.1                 
498 salcianu 1.1                 return hms[i];
499 salcianu 1.1             }
500 salcianu 1.1         }
501 salcianu 1.1 
502 salcianu 1.1         return null;
503 salcianu 1.1     }
504 salcianu 1.1 
505 salcianu 1.1 
506 salcianu 1.1     // Returns a set that contains all the Temps that appear in the first
507 salcianu 1.1     // position (ie the this pointer) in one of the CALLs in calls.
508 salcianu 1.1     private Set/*<ExactTemp>*/ get_ietemps(Set/*<CALL>*/ calls) {
509 salcianu 1.1         Set/*<ExactTemp>*/ temps = new HashSet/*<ExactTemp>*/();
510 salcianu 1.1         for(Iterator/*<CALL>*/ it = calls.iterator(); it.hasNext(); ) {
511 salcianu 1.1             CALL cs = (CALL) it.next();
512 salcianu 1.1             temps.add(new ExactTemp(cs, cs.params(1)));
513 salcianu 1.1         }
514 salcianu 1.1         return temps;
515 salcianu 1.1     }
516 salcianu 1.1 
517 salcianu 1.1     /////////////////// get_entered_runs END  ////////////////////////
518 salcianu 1.1 
519 salcianu 1.1 
520 salcianu 1.1     private boolean nothing_escapes(HMethod hm) {
521 salcianu 1.1         // if(DEBUG_RT)
522 salcianu 1.1             System.out.println("RTJ: nothing_escapes(" + hm + ") entered");
523 salcianu 1.1 
524 salcianu 1.1         ParIntGraph pig = null;
525 salcianu 1.1 
526 salcianu 1.1         if(RTJ_CR_POLICY == RTJ_CR_INTER_PROC)
527 salcianu 1.1             pig = pa.getExtParIntGraph(hm2mm(hm));
528 salcianu 1.1         else if(RTJ_CR_POLICY == RTJ_CR_INTER_THREAD)
529 salcianu 1.1             pig = pa.threadInteraction(hm2mm(hm));
530 salcianu 1.1         else {
531 salcianu 1.1             System.out.println("Unknown RTJ_CR_POLICY !");
532 salcianu 1.1             System.exit(1);
533 salcianu 1.1         }
534 salcianu 1.1 
535 salcianu 1.1         pig = (ParIntGraph) pig.clone();
536 salcianu 1.1         // we don't care about the exceptions; if an exception is thrown
537 salcianu 1.1         // out of the run method of a thread, the program is gonna stop with
538 salcianu 1.1         // an exception anyway.
539 salcianu 1.1         pig.G.excp.clear();
540 salcianu 1.1 
541 salcianu 1.1         //TODO: some of the native methods are not harmful:
542 salcianu 1.1         //   java.lang.Object.getClass()
543 salcianu 1.1         //   java.lang.Thread.isAlive() etc.
544 salcianu 1.1         // make sure we clean the graph a bit before looking at it
545 salcianu 1.1         // (there should be more info about this in MAInfo)
546 salcianu 1.1         pig.G.flushCaches();
547 salcianu 1.1         pig.G.e.removeMethodHoles
548 salcianu 1.1             (harpoon.Analysis.PointerAnalysis.InterProcPA.
549 salcianu 1.1              getUnharmfulMethods());
550 salcianu 1.1 
551 salcianu 1.1         if(DEBUG_RT)
552 salcianu 1.1             System.out.println("pig = " + pig + "\n\n");
553 salcianu 1.1 
554 salcianu 1.1         Set/*<PANode>*/ nodes = pig.allNodes();
555 salcianu 1.1         for(Iterator/*<PANode>*/ it = nodes.iterator(); it.hasNext(); ) {
556 salcianu 1.1             PANode node = (PANode) it.next();
557 salcianu 1.1             if((node.type() == PANode.INSIDE) &&
558 salcianu 1.1                !pig.G.captured(node)) {
559 salcianu 1.1                 System.out.println
560 salcianu 1.1                     ("RTJ: " + node + " created at " + 
561 salcianu 1.1                      Util.code2str(pa.getNodeRepository().node2Code
562 salcianu 1.1                                    (node.getRoot())) +
563 salcianu 1.1                      " escapes -> false");
564 salcianu 1.1                 return false;
565 salcianu 1.1             }
566 salcianu 1.1         }
567 salcianu 1.1 
568 salcianu 1.1         if(DEBUG_RT)
569 salcianu 1.1             System.out.println("RTJ: Nothing escapes from " + hm + " !!!");
570 salcianu 1.1         return true;
571 salcianu 1.1     }
572 salcianu 1.1 
573 salcianu 1.1     //////////////////// RTJ CHECK REMOVAL ENDS //////////////////////////
574 salcianu 1.1     //////////////////////////////////////////////////////////////////////
575 salcianu 1.1 
576 salcianu 1.1     private static long time() {
577 salcianu 1.1         return System.currentTimeMillis();
578 salcianu 1.1     }
579 salcianu 1.1 }