1 salcianu 1.1.2.1 // MetaCallGraphAbstr.java, created Mon Mar 13 16:03:18 2000 by salcianu 2 cananian 1.1.2.12 // Copyright (C) 2000 Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu> 3 salcianu 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 salcianu 1.1.2.1 package harpoon.Analysis.MetaMethods; 5 salcianu 1.1.2.1 6 salcianu 1.1.2.1 import java.util.Set; 7 salcianu 1.1.2.1 import java.util.HashSet; 8 salcianu 1.1.2.1 import java.util.Map; 9 salcianu 1.1.2.1 import java.util.HashMap; 10 salcianu 1.1.2.1 import java.util.Collections; 11 salcianu 1.1.2.2 import java.util.Iterator; 12 salcianu 1.1.2.4 import java.util.LinkedList; 13 salcianu 1.1.2.2 14 salcianu 1.4 import java.io.PrintStream; 15 salcianu 1.1.2.1 16 salcianu 1.1.2.1 import harpoon.IR.Quads.CALL; 17 salcianu 1.1.2.3 import harpoon.ClassFile.HCodeElement; 18 salcianu 1.1.2.1 19 salcianu 1.1.2.10 import harpoon.Util.DataStructs.Relation; 20 salcianu 1.1.2.11 import harpoon.Util.DataStructs.RelationImpl; 21 salcianu 1.1.2.10 import harpoon.Util.DataStructs.RelationEntryVisitor; 22 salcianu 1.1.2.10 23 salcianu 1.1.2.1 /** 24 salcianu 1.5 * <code>MetaCallGraphAbstr</code> Map based abstract 25 salcianu 1.5 * <code>MetaCallGraph</code>. 26 salcianu 1.1.2.1 * 27 cananian 1.1.2.12 * @author Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu> 28 cananian 1.7 * @version $Id: MetaCallGraphAbstr.java,v 1.7 2004/02/08 03:19:57 cananian Exp $ */ 29 salcianu 1.5 public abstract class MetaCallGraphAbstr extends MetaCallGraph { 30 salcianu 1.1.2.1 // Map<MetaMethod,MetaMethod[]> 31 salcianu 1.1.2.1 protected final Map callees1_cmpct = new HashMap(); 32 salcianu 1.1.2.1 // Map<MetaMethod,Map<CALL,MetaMethod[]>> 33 salcianu 1.1.2.1 protected final Map callees2_cmpct = new HashMap(); 34 salcianu 1.1.2.1 35 salcianu 1.1.2.1 private final MetaMethod[] empty_array = new MetaMethod[0]; 36 salcianu 1.1.2.1 37 salcianu 1.1.2.1 /** Returns the meta methods that can be called by <code>mm</code>. */ 38 salcianu 1.5 public MetaMethod[] getCallees(MetaMethod mm) { 39 salcianu 1.1.2.1 MetaMethod[] retval = (MetaMethod[]) callees1_cmpct.get(mm); 40 salcianu 1.1.2.1 if(retval == null) 41 salcianu 1.1.2.1 retval = empty_array; 42 salcianu 1.1.2.1 return retval; 43 salcianu 1.1.2.1 } 44 salcianu 1.1.2.1 45 salcianu 1.1.2.1 /** Returns the meta methods that can be called by <code>mm</code> 46 salcianu 1.1.2.1 at the call site <code>q</code>. */ 47 salcianu 1.5 public MetaMethod[] getCallees(MetaMethod mm, CALL cs) { 48 salcianu 1.1.2.1 Map map = (Map) callees2_cmpct.get(mm); 49 salcianu 1.1.2.1 if(map == null) 50 salcianu 1.1.2.1 return new MetaMethod[0]; 51 salcianu 1.1.2.1 MetaMethod[] retval = (MetaMethod[]) map.get(cs); 52 salcianu 1.1.2.1 if(retval == null) 53 salcianu 1.1.2.1 retval = empty_array; 54 salcianu 1.1.2.1 return retval; 55 salcianu 1.1.2.1 } 56 salcianu 1.1.2.4 57 salcianu 1.6 /** Returns the set of all the meta methods that might be called, 58 salcianu 1.6 directly or indirectly, by meta method <code>mm</code>. */ 59 salcianu 1.6 public Set getTransCallees(MetaMethod mm) { 60 salcianu 1.6 return transitiveSucc(mm); 61 salcianu 1.1.2.4 } 62 salcianu 1.1.2.4 63 salcianu 1.1.2.1 64 salcianu 1.1.2.1 /** Returns the set of all the call sites in the code of the meta-method 65 salcianu 1.1.2.1 <code>mm</code>. */ 66 salcianu 1.6 public Set/*<CALL>*/ getCallSites(MetaMethod mm){ 67 salcianu 1.1.2.1 Map map = (Map) callees2_cmpct.get(mm); 68 salcianu 1.1.2.1 if(map == null) 69 salcianu 1.1.2.1 return Collections.EMPTY_SET; 70 salcianu 1.1.2.1 return map.keySet(); 71 salcianu 1.1.2.1 } 72 salcianu 1.1.2.1 73 salcianu 1.3 // set of all encountered meta methods 74 salcianu 1.1.2.1 protected final Set all_meta_methods = new HashSet(); 75 salcianu 1.1.2.1 76 salcianu 1.1.2.1 /** Returns the set of all the meta methods that might be called during the 77 salcianu 1.1.2.1 execution of the program. */ 78 salcianu 1.1.2.1 public Set getAllMetaMethods(){ 79 salcianu 1.1.2.1 return all_meta_methods; 80 salcianu 1.1.2.1 } 81 salcianu 1.1.2.2 82 salcianu 1.1.2.2 /** Computes the <i>split</i> relation. This is a <code>Relation</code> 83 salcianu 1.1.2.2 that associates to each <code>HMethod</code> the set of 84 salcianu 1.1.2.2 <code>MetaMethod</code>s specialized from it. */ 85 salcianu 1.1.2.2 public Relation getSplitRelation(){ 86 salcianu 1.1.2.2 if(split != null) return split; 87 salcianu 1.1.2.11 split = new RelationImpl(); 88 cananian 1.7 for(Object mmO : getAllMetaMethods()){ 89 cananian 1.7 MetaMethod mm = (MetaMethod) mmO; 90 salcianu 1.1.2.2 split.add(mm.getHMethod(), mm); 91 salcianu 1.1.2.2 } 92 salcianu 1.1.2.2 return split; 93 salcianu 1.1.2.2 } 94 salcianu 1.1.2.2 // keeps the split relation 95 salcianu 1.1.2.2 private Relation split = null; 96 salcianu 1.1.2.2 97 salcianu 1.1.2.7 98 salcianu 1.1.2.8 protected Set run_mms = new HashSet(); 99 salcianu 1.1.2.7 public Set getRunMetaMethods(){ 100 salcianu 1.1.2.8 return run_mms; 101 salcianu 1.1.2.7 } 102 salcianu 1.1.2.7 103 salcianu 1.1.2.7 104 salcianu 1.1.2.2 /** Nice pretty-printer for debug purposes. */ 105 salcianu 1.4 public void print(PrintStream ps, boolean detailed_view, MetaMethod root) { 106 cananian 1.7 for(Object mmO : getAllMetaMethods()) { 107 cananian 1.7 MetaMethod mm = (MetaMethod) mmO; 108 salcianu 1.4 ps.println(); 109 salcianu 1.4 ps.print(mm); 110 salcianu 1.4 if(detailed_view) { 111 salcianu 1.4 ps.println(); 112 cananian 1.7 for(Object csO : getCallSites(mm)){ 113 cananian 1.7 CALL cs = (CALL) csO; 114 salcianu 1.1.2.3 HCodeElement hce = (HCodeElement) cs; 115 salcianu 1.1.2.2 MetaMethod[] callees = getCallees(mm,cs); 116 salcianu 1.4 ps.println(" " + hce.getSourceFile() + ":" + 117 salcianu 1.1.2.3 hce.getLineNumber() + " " + cs + " (" + 118 salcianu 1.1.2.3 callees.length + " callee(s)):"); 119 salcianu 1.1.2.2 for(int i = 0; i < callees.length; i++) 120 salcianu 1.4 ps.println(" " + callees[i]); 121 salcianu 1.1.2.2 } 122 salcianu 1.1.2.2 } 123 salcianu 1.4 else { 124 salcianu 1.1.2.2 MetaMethod[] callees = getCallees(mm); 125 salcianu 1.4 ps.println(" (" + callees.length + " callee(s)) :"); 126 salcianu 1.1.2.2 for(int i = 0; i < callees.length; i++) 127 salcianu 1.4 ps.println(" " + callees[i]); 128 salcianu 1.1.2.2 } 129 salcianu 1.1.2.2 } 130 salcianu 1.1.2.2 } 131 cananian 1.2 }