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      }