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 }