1 salcianu 1.1.2.1 // FakeMetaCallGraph.java, created Mon Mar 13 15:56:57 2000 by salcianu
  2 cananian 1.1.2.7 // 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.Map;
  8 salcianu 1.1.2.1 import java.util.HashMap;
  9 salcianu 1.1.2.1 import java.util.Iterator;
 10 salcianu 1.1.2.1 
 11 salcianu 1.1.2.1 import harpoon.Analysis.Quads.CallGraph;
 12 salcianu 1.1.2.1 import harpoon.ClassFile.HMethod;
 13 salcianu 1.1.2.1 import harpoon.IR.Quads.CALL;
 14 salcianu 1.1.2.1 
 15 salcianu 1.1.2.1 /**
 16 salcianu 1.1.2.1  * <code>FakeMetaCallGraph</code> converts a classic <code>CallGraph</code> to
 17 salcianu 1.1.2.1  a <code>MetaCallGraph</code>. Basically, it offers a <i>MetaMethods</i>-view
 18 salcianu 1.1.2.1  of the call graph, without doing any specialization. This is possible because
 19 salcianu 1.1.2.2  there is an obvious mapping from each method of the program to an
 20 salcianu 1.1.2.2  unspecialized meta-method consisting of that method plus its declared
 21 salcianu 1.1.2.5  parameter types (marked as polymorphic to cope with all the possible ways
 22 salcianu 1.1.2.5  that method could be called).
 23 salcianu 1.1.2.1 
 24 salcianu 1.1.2.5  Although it doesn't offer any additional power,
 25 salcianu 1.1.2.2  <code>FakeMetaCallGraph</code> allows the use of the components that require
 26 salcianu 1.1.2.2  &quot;meta methods&quot; even without specializing methods to meta-methods.
 27 salcianu 1.1.2.2  For example, if you need to use the <code>PointerAnalysis</code> stuff, but
 28 salcianu 1.1.2.2  don't feel very comfortable with meta-methods, just pass it a 
 29 salcianu 1.1.2.2  <code>FakeMetaCallGraph</code>.
 30 salcianu 1.1.2.1  * 
 31 cananian 1.1.2.7  * @author  Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu>
 32 cananian 1.7      * @version $Id: FakeMetaCallGraph.java,v 1.7 2004/02/08 03:19:57 cananian Exp $
 33 salcianu 1.1.2.1  */
 34 salcianu 1.1.2.1 public class FakeMetaCallGraph extends MetaCallGraphAbstr {
 35 salcianu 1.1.2.1 
 36 salcianu 1.1.2.1     /** Creates a <code>FakeMetaCallGraph</code>. Receives as parameters
 37 salcianu 1.4           a <code>CallGraph</code> object.
 38 salcianu 1.1.2.1       The resulting <code>FakeMetaCallGraph</code> object is just a
 39 salcianu 1.1.2.1       <code>MetaMethod</code> view of the data contained into <code>cg</code>.
 40 salcianu 1.1.2.1     */
 41 salcianu 1.4         public FakeMetaCallGraph(CallGraph cg, Set runs) {
 42 salcianu 1.4             Map map = create_map(cg.callableMethods());
 43 salcianu 1.1.2.5         translate(cg, map);
 44 salcianu 1.1.2.3 
 45 salcianu 1.6             // initialize the set of callable "run" methods.
 46 salcianu 1.5             if(runs != null) {
 47 salcianu 1.6                 run_mms.addAll(runs);
 48 salcianu 1.5             }
 49 salcianu 1.5             else {
 50 salcianu 1.4                 // try to get run_mms through some other means
 51 salcianu 1.4                 for(Iterator it = cg.getRunMethods().iterator(); it.hasNext(); )
 52 salcianu 1.4                     run_mms.add(new MetaMethod((HMethod) it.next(), true));
 53 salcianu 1.4             }
 54 salcianu 1.4         }
 55 salcianu 1.4     
 56 salcianu 1.4         public FakeMetaCallGraph(CallGraph cg) {
 57 salcianu 1.4             this(cg, null);
 58 salcianu 1.1.2.1     }
 59 salcianu 1.1.2.1 
 60 salcianu 1.1.2.1     // Create the HMethod -> MetaMethod one-to-one map.
 61 salcianu 1.1.2.1     private Map create_map(Set methods){
 62 salcianu 1.1.2.1         Map map = new HashMap();
 63 cananian 1.7             for(Object hmO : methods){
 64 cananian 1.7                 HMethod hm = (HMethod) hmO;
 65 salcianu 1.1.2.1             MetaMethod mm = new MetaMethod(hm);
 66 salcianu 1.3                 map.put(hm, mm);
 67 salcianu 1.1.2.1         }
 68 salcianu 1.1.2.1         return map;
 69 salcianu 1.1.2.1     }
 70 salcianu 1.1.2.1 
 71 salcianu 1.1.2.4     // Translate the info from the CallGraph into this MetaCallGraph using map
 72 salcianu 1.1.2.1     private void translate(CallGraph cg, Map map){
 73 salcianu 1.1.2.1 
 74 salcianu 1.3             // set the all_meta_methods set
 75 cananian 1.7             for(Object hmO : map.keySet()){
 76 cananian 1.7                 HMethod hm = (HMethod) hmO;
 77 salcianu 1.1.2.1             MetaMethod mm = (MetaMethod) map.get(hm);
 78 salcianu 1.1.2.1             all_meta_methods.add(mm);
 79 salcianu 1.1.2.1         }
 80 salcianu 1.1.2.1         
 81 salcianu 1.1.2.1         // fill the callees1_cmpct map
 82 cananian 1.7             for(Object hmO : map.keySet()){
 83 cananian 1.7                 HMethod hm = (HMethod) hmO;
 84 salcianu 1.1.2.1             MetaMethod mm = (MetaMethod) map.get(hm);
 85 salcianu 1.1.2.1             MetaMethod[] mmc = hms2mms(cg.calls(hm),map);
 86 salcianu 1.1.2.1             callees1_cmpct.put(mm,mmc);
 87 salcianu 1.1.2.1         }
 88 salcianu 1.1.2.1         // fill the callees2_cmpct map
 89 cananian 1.7             for(Object hmO : map.keySet()){
 90 cananian 1.7                 HMethod hm = (HMethod) hmO;
 91 salcianu 1.1.2.1             MetaMethod mm = (MetaMethod) map.get(hm);
 92 salcianu 1.1.2.1             CALL[] css = cg.getCallSites(hm);
 93 salcianu 1.1.2.1             for(int i = 0; i < css.length; i++){
 94 salcianu 1.1.2.1                 CALL cs = css[i];
 95 salcianu 1.1.2.1                 MetaMethod[] mmc = hms2mms(cg.calls(hm,cs),map);
 96 salcianu 1.1.2.1                 Map cs2mm = (Map) callees2_cmpct.get(mm);
 97 salcianu 1.1.2.1                 if(cs2mm == null)
 98 salcianu 1.1.2.1                     callees2_cmpct.put(mm, cs2mm = new HashMap());
 99 salcianu 1.1.2.1                 cs2mm.put(cs,mmc);
100 salcianu 1.1.2.1             }
101 salcianu 1.1.2.1         }
102 salcianu 1.1.2.1     }
103 salcianu 1.1.2.1 
104 salcianu 1.1.2.1     // convert an array of HMethod's into an array of MetaMethod,
105 salcianu 1.1.2.1     // according to map.
106 salcianu 1.1.2.1     private MetaMethod[] hms2mms(HMethod[] hms, Map map){
107 salcianu 1.1.2.1         MetaMethod[] mms = new MetaMethod[hms.length];
108 salcianu 1.1.2.1         for(int i = 0; i < hms.length; i++)
109 salcianu 1.1.2.1             mms[i] = (MetaMethod) map.get(hms[i]);
110 salcianu 1.1.2.1         return mms;
111 salcianu 1.1.2.1     }
112 cananian 1.2     }