1 salcianu 1.1.2.1 // NodeRepository.java, created Wed Jan 12 14:14:27 2000 by salcianu 2 cananian 1.1.2.3 // 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.PointerAnalysis; 5 salcianu 1.1.2.1 6 salcianu 1.1.2.1 import java.util.Hashtable; 7 salcianu 1.1.2.11 import java.util.Set; 8 salcianu 1.1.2.5 import java.util.Iterator; 9 salcianu 1.1.2.13 import java.util.Map; 10 salcianu 1.1.2.1 11 salcianu 1.1.2.21 import java.lang.reflect.Modifier; 12 salcianu 1.1.2.21 13 salcianu 1.7 import harpoon.ClassFile.Linker; 14 salcianu 1.1.2.1 import harpoon.ClassFile.HMethod; 15 salcianu 1.1.2.26 import harpoon.ClassFile.HClass; 16 salcianu 1.1.2.1 import harpoon.ClassFile.HCodeElement; 17 salcianu 1.1.2.5 import harpoon.IR.Quads.Quad; 18 salcianu 1.1.2.26 import harpoon.IR.Quads.QuadVisitor; 19 salcianu 1.1.2.11 import harpoon.IR.Quads.CALL; 20 salcianu 1.1.2.26 import harpoon.IR.Quads.NEW; 21 salcianu 1.1.2.26 import harpoon.IR.Quads.ANEW; 22 salcianu 1.1.2.26 import harpoon.IR.Quads.GET; 23 salcianu 1.1.2.26 import harpoon.IR.Quads.AGET; 24 salcianu 1.1.2.1 25 salcianu 1.1.2.12 import harpoon.Analysis.MetaMethods.MetaMethod; 26 salcianu 1.1.2.26 import harpoon.Analysis.MetaMethods.GenType; 27 salcianu 1.1.2.26 28 salcianu 1.1.2.26 import harpoon.Util.Util; 29 salcianu 1.1.2.12 30 salcianu 1.1.2.1 /** 31 salcianu 1.1.2.1 * <code>NodeRepository</code> 32 salcianu 1.1.2.1 * 33 cananian 1.1.2.33 * @author Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu> 34 cananian 1.10 * @version $Id: NodeRepository.java,v 1.10 2004/02/08 03:20:02 cananian Exp $ 35 salcianu 1.1.2.1 */ 36 salcianu 1.1.2.30 public class NodeRepository implements java.io.Serializable { 37 salcianu 1.1.2.34 38 salcianu 1.8 public final static PANode NULL_NODE = getNewNode(PANode.NULL); 39 salcianu 1.8 40 salcianu 1.8 // this node acts as a summary for all load nodes that escape into 41 salcianu 1.8 // an unanalyzed method or into a static node. 42 salcianu 1.8 public final static PANode LOST_SUMMARY = getNewNode(PANode.LOST); 43 salcianu 1.1.2.1 44 salcianu 1.7 private Hashtable/*<String,PANode>*/ static_nodes; 45 salcianu 1.7 private Hashtable/*<HMethod,PANode[]>*/ param_nodes; 46 salcianu 1.7 private Hashtable/*<Quad,PANode>*/ code_nodes; 47 salcianu 1.7 private Hashtable/*<CFPair,PANode>*/ cf_nodes; 48 salcianu 1.7 private Hashtable/*<Quad,PANode>*/ except_nodes; 49 salcianu 1.7 private Hashtable/*<PANode,Quad>*/ node2code; 50 salcianu 1.1.2.1 51 salcianu 1.1.2.1 /** Creates a <code>NodeRepository</code>. */ 52 salcianu 1.7 public NodeRepository(Linker linker) { 53 salcianu 1.1.2.1 static_nodes = new Hashtable(); 54 salcianu 1.1.2.1 param_nodes = new Hashtable(); 55 salcianu 1.1.2.1 code_nodes = new Hashtable(); 56 salcianu 1.1.2.20 cf_nodes = new Hashtable(); 57 salcianu 1.1.2.9 except_nodes = new Hashtable(); 58 salcianu 1.1.2.7 node2code = new Hashtable(); 59 salcianu 1.8 jl_Throwable = linker.forName("java.lang.Throwable"); 60 salcianu 1.8 jl_Object = linker.forName("java.lang.Object"); 61 salcianu 1.1.2.1 } 62 salcianu 1.1.2.1 63 salcianu 1.1.2.31 // debug flag: if it's set on, it shows how each node is created 64 salcianu 1.8 private final static boolean SHOW_NODE_CREATION = true; 65 salcianu 1.1.2.31 66 salcianu 1.7 67 salcianu 1.7 /** Returns the node that models the constant object 68 salcianu 1.7 <code>value</code>. Currently, all constant objects are 69 salcianu 1.7 modelled by a single node. */ 70 salcianu 1.7 public final PANode getConstNode(Object value) { 71 salcianu 1.8 if(value == null) 72 salcianu 1.8 return NULL_NODE; 73 salcianu 1.7 return CONST_NODE; 74 salcianu 1.7 } 75 salcianu 1.8 // should be private 76 salcianu 1.8 static final PANode CONST_NODE = getNewNode(PANode.CONST); 77 salcianu 1.7 78 salcianu 1.1.2.4 /** Returns the static node associated with the class 79 salcianu 1.1.2.4 * <code>class_name</code>. The node is automatically created if it 80 salcianu 1.1.2.4 * doesn't exist yet. <code>class_name</code> MUST be the full 81 salcianu 1.1.2.4 * (and hence unique) name of the class */ 82 salcianu 1.8 public final PANode getStaticNode(String class_name) { 83 salcianu 1.8 84 salcianu 1.8 if(PointerAnalysis.COMPRESS_LOST_NODES) 85 salcianu 1.8 return LOST_SUMMARY; 86 salcianu 1.8 87 salcianu 1.1.2.5 PANode node = (PANode) static_nodes.get(class_name); 88 salcianu 1.1.2.26 if(node == null) { 89 salcianu 1.1.2.26 node = getNewNode(PANode.STATIC, null); // TODO 90 salcianu 1.1.2.26 static_nodes.put(class_name, node); 91 salcianu 1.1.2.31 92 salcianu 1.1.2.31 if(SHOW_NODE_CREATION) 93 salcianu 1.1.2.31 System.out.println("CREATED NODE " + node + 94 salcianu 1.1.2.31 " for " + class_name); 95 salcianu 1.1.2.26 } 96 salcianu 1.1.2.4 return node; 97 salcianu 1.1.2.1 } 98 salcianu 1.1.2.1 99 salcianu 1.1.2.12 /** Creates all the parameter nodes associated with <code>mmethod</code>. 100 salcianu 1.1.2.1 * <code>param_number</code> must contain the number of formal 101 salcianu 1.1.2.12 * parameters of the meta-method. */ 102 salcianu 1.8 public final void addParamNodes(MetaMethod mmethod, int param_number) { 103 salcianu 1.1.2.4 // do not create the parameter nodes twice for the same procedure 104 salcianu 1.1.2.12 if(param_nodes.containsKey(mmethod)) return; 105 salcianu 1.1.2.27 // grab the types for the method's object parameters 106 salcianu 1.1.2.27 GenType[] gts = new GenType[param_number]; 107 salcianu 1.1.2.27 int count = 0; 108 salcianu 1.1.2.27 for(int i = 0; i < mmethod.nbParams(); i++) { 109 salcianu 1.1.2.27 GenType gt = mmethod.getType(i); 110 salcianu 1.1.2.27 if(!gt.getHClass().isPrimitive()) { 111 salcianu 1.7 assert count < param_number : 112 salcianu 1.7 "Strange number of params for " + mmethod; 113 salcianu 1.1.2.27 gts[count] = gt; 114 salcianu 1.1.2.27 count++; 115 salcianu 1.1.2.27 } 116 salcianu 1.1.2.27 } 117 salcianu 1.1.2.27 // do the essential thing: create the nodes 118 salcianu 1.1.2.1 PANode nodes[] = new PANode[param_number]; 119 salcianu 1.1.2.26 for(int i = 0; i < param_number; i++) 120 salcianu 1.1.2.27 nodes[i] = getNewNode(PANode.PARAM, new GenType[]{gts[i]}); 121 salcianu 1.1.2.12 param_nodes.put(mmethod,nodes); 122 salcianu 1.1.2.31 123 salcianu 1.1.2.31 if(SHOW_NODE_CREATION && (nodes.length > 0)) { 124 salcianu 1.1.2.31 System.out.print("\nCREATED NODES "); 125 salcianu 1.1.2.31 for(int i = 0; i < nodes.length; i++) 126 salcianu 1.1.2.31 System.out.print(" " + nodes[i]); 127 salcianu 1.1.2.31 System.out.println("; parameters for " + mmethod.getHMethod()); 128 salcianu 1.1.2.31 } 129 salcianu 1.1.2.1 } 130 salcianu 1.1.2.1 131 salcianu 1.1.2.4 /** Returns the parameter node associated with the <code>count</code>th 132 salcianu 1.1.2.12 * formal parameter of <code>mmethod</code>. The parameter nodes for 133 salcianu 1.1.2.12 * <code>mmethod</code> should be created in advance, using 134 salcianu 1.1.2.4 * <code>addParamNodes</code>. */ 135 salcianu 1.1.2.12 public final PANode getParamNode(MetaMethod mmethod, int count){ 136 salcianu 1.1.2.1 // The runtime system will take care of all the debug messages ... 137 salcianu 1.1.2.12 return getAllParams(mmethod)[count]; 138 salcianu 1.1.2.1 } 139 salcianu 1.1.2.1 140 salcianu 1.1.2.4 /** Returns all the parameter nodes associated with the 141 salcianu 1.1.2.12 * formal parameters of <code>mmethod</code>. The parameter nodes for 142 salcianu 1.1.2.12 * <code>mmethod</code> should be 143 salcianu 1.1.2.4 * created in advance, using <code>addParamNodes</code>. */ 144 salcianu 1.1.2.12 public final PANode[] getAllParams(MetaMethod mmethod){ 145 salcianu 1.1.2.1 if(PointerAnalysis.DEBUG){ 146 salcianu 1.1.2.21 if(!param_nodes.containsKey(mmethod) && 147 salcianu 1.1.2.21 !Modifier.isNative(mmethod.getHMethod().getModifiers())) { 148 salcianu 1.1.2.1 System.out.println("getAllParams: inexistent nodes"); 149 salcianu 1.1.2.1 System.exit(1); 150 salcianu 1.1.2.21 } 151 salcianu 1.1.2.1 } 152 salcianu 1.1.2.12 return (PANode[]) param_nodes.get(mmethod); 153 salcianu 1.1.2.1 } 154 salcianu 1.1.2.1 155 salcianu 1.1.2.26 private final GenType[] get_exceptions(HMethod callee) { 156 salcianu 1.1.2.26 HClass[] excs = callee.getExceptionTypes(); 157 salcianu 1.1.2.26 GenType[] retval = new GenType[excs.length]; 158 salcianu 1.1.2.26 for(int i = 0; i < excs.length; i++) 159 salcianu 1.1.2.26 retval[i] = new GenType(excs[i], GenType.POLY); 160 salcianu 1.1.2.26 return retval; 161 salcianu 1.1.2.26 } 162 salcianu 1.1.2.26 163 salcianu 1.1.2.9 // Returns the EXCEPT node associated with a CALL instruction 164 salcianu 1.1.2.9 private final PANode getExceptNode(HCodeElement hce){ 165 salcianu 1.7 if(COALESCE_RESULTS_FROM_NATIVES) { 166 salcianu 1.7 if(coalesced_native_excp == null) 167 salcianu 1.7 coalesced_native_excp = getNewNode(PANode.EXCEPT); 168 salcianu 1.7 return coalesced_native_excp; 169 salcianu 1.7 } 170 salcianu 1.7 171 salcianu 1.1.2.9 PANode node = (PANode) except_nodes.get(hce); 172 salcianu 1.1.2.26 if(node == null) { 173 salcianu 1.1.2.26 HMethod callee = ((CALL) hce).method(); 174 salcianu 1.1.2.26 node = getNewNode(PANode.EXCEPT, get_exceptions(callee)); 175 salcianu 1.1.2.26 except_nodes.put(hce, node); 176 salcianu 1.1.2.26 node2code.put(node, hce); 177 salcianu 1.1.2.9 } 178 salcianu 1.1.2.9 return node; 179 salcianu 1.1.2.9 } 180 salcianu 1.7 private PANode coalesced_native_excp = null; 181 salcianu 1.7 private PANode coalesced_native_ret = null; 182 salcianu 1.7 private final boolean COALESCE_RESULTS_FROM_NATIVES = true; 183 salcianu 1.7 private PANode coalesced_excp = null; 184 salcianu 1.8 private final HClass jl_Throwable; 185 salcianu 1.8 private final HClass jl_Object; 186 salcianu 1.7 private final boolean COALESCE_EXCEPTIONS = true; 187 salcianu 1.1.2.9 188 salcianu 1.1.2.20 // Auxiliary class: the key type for the "cf_nodes" hashtable. 189 salcianu 1.1.2.30 private static class CFPair implements java.io.Serializable { 190 salcianu 1.1.2.20 HCodeElement hce; 191 salcianu 1.1.2.20 String f; 192 salcianu 1.1.2.20 CFPair(HCodeElement hce, String f){ 193 salcianu 1.1.2.20 this.hce = hce; 194 salcianu 1.1.2.20 this.f = f; 195 salcianu 1.1.2.20 } 196 salcianu 1.1.2.20 197 salcianu 1.1.2.20 int hash = 0; // small caching hack 198 salcianu 1.1.2.20 public int hashCode(){ 199 salcianu 1.1.2.20 if(hash == 0) 200 salcianu 1.1.2.20 hash = hce.hashCode() + f.hashCode(); 201 salcianu 1.1.2.20 return hash; 202 salcianu 1.1.2.20 } 203 salcianu 1.1.2.20 204 salcianu 1.1.2.20 public boolean equals(Object obj){ 205 salcianu 1.1.2.20 CFPair hf2 = (CFPair) obj; 206 salcianu 1.1.2.20 return (hf2.hce.equals(hce) && hf2.f.equals(f)); 207 salcianu 1.1.2.20 } 208 salcianu 1.1.2.20 209 salcianu 1.1.2.20 public String toString(){ 210 salcianu 1.1.2.20 return hce.toString() + f.toString(); 211 salcianu 1.1.2.20 } 212 salcianu 1.1.2.20 } 213 salcianu 1.1.2.20 214 salcianu 1.1.2.20 /** Special function for load instructions that read multiple fields 215 salcianu 1.1.2.20 in the same time (the motivating example is that of "clone()") 216 salcianu 1.1.2.20 For such an instruction, a load node is generated for each field 217 salcianu 1.1.2.20 that is read (<code>f</code> in the parameter list). */ 218 salcianu 1.1.2.20 public final PANode getLoadNodeSpecial(HCodeElement hce, String f){ 219 salcianu 1.1.2.20 CFPair key = new CFPair(hce, f); 220 salcianu 1.1.2.20 PANode retval = (PANode) cf_nodes.get(key); 221 salcianu 1.1.2.26 if(retval == null) { 222 salcianu 1.1.2.20 retval = new PANode(PANode.LOAD); 223 salcianu 1.1.2.20 cf_nodes.put(key, retval); 224 salcianu 1.1.2.20 } 225 salcianu 1.1.2.20 return retval; 226 salcianu 1.1.2.20 } 227 salcianu 1.1.2.20 228 salcianu 1.1.2.20 229 salcianu 1.8 public final PANode getCodeNode(HCodeElement hce, int type) { 230 salcianu 1.8 return getCodeNode(hce, type, null, true); 231 salcianu 1.8 } 232 salcianu 1.8 233 salcianu 1.8 public final PANode getCodeNode(HCodeElement hce, int type, boolean make) { 234 salcianu 1.8 return getCodeNode(hce, type, null, make); 235 salcianu 1.8 } 236 salcianu 1.8 237 salcianu 1.1.2.24 /** Returns a <i>code</i> node: a node associated with the 238 salcianu 1.1.2.4 * instruction <code>hce</code>: a load node 239 salcianu 1.1.2.4 * (associated with a <code>GET</code> quad), a return node (associated 240 salcianu 1.1.2.4 * with a <code>CALL</code>) or an inside node (thread or not) associated 241 salcianu 1.1.2.4 * with a <code>NEW</code>). The node is automatically created if it 242 salcianu 1.1.2.4 * doesn't exist yet. The type of the node should be passed in the 243 salcianu 1.1.2.4 * <code>type</code> argument. */ 244 salcianu 1.8 public final PANode getCodeNode(HCodeElement hce, int type, GenType[] gts){ 245 salcianu 1.8 return getCodeNode(hce, type, gts, true); 246 salcianu 1.1.2.24 } 247 salcianu 1.1.2.24 248 salcianu 1.1.2.24 /** Returns a <i>code</i> node: a node associated with an instruction. 249 salcianu 1.1.2.24 The boolean parameter <code>make</code> controls the generation of 250 salcianu 1.1.2.24 such a node in case it doesn't exist yet. */ 251 salcianu 1.8 public final PANode getCodeNode(HCodeElement hce, int type, GenType[] gts, 252 salcianu 1.8 boolean make) { 253 salcianu 1.8 254 salcianu 1.9 if(((type == PANode.RETURN) || (type == PANode.EXCEPT)) && 255 salcianu 1.8 PointerAnalysis.COMPRESS_LOST_NODES) 256 salcianu 1.8 return LOST_SUMMARY; 257 salcianu 1.8 258 salcianu 1.1.2.9 // we can have a RETURN node and an EXCEPT node associated to the 259 salcianu 1.1.2.9 // same code instruction. This is the only case where we have 260 salcianu 1.1.2.9 // two nodes associated with an instruction. We fix this by handling 261 salcianu 1.1.2.9 // EXCEPT nodes separately. 262 salcianu 1.1.2.9 if(type == PANode.EXCEPT) return getExceptNode(hce); 263 salcianu 1.1.2.9 264 salcianu 1.7 if(type == PANode.RETURN && COALESCE_RESULTS_FROM_NATIVES) { 265 salcianu 1.7 if(coalesced_native_ret == null) 266 salcianu 1.8 coalesced_native_ret = 267 salcianu 1.8 getNewNode 268 salcianu 1.8 (PANode.RETURN, 269 salcianu 1.8 new GenType[] { new GenType(jl_Object, GenType.POLY) }); 270 salcianu 1.7 return coalesced_native_ret; 271 salcianu 1.7 } 272 salcianu 1.7 273 salcianu 1.7 if((type == PANode.INSIDE) && COALESCE_EXCEPTIONS && 274 salcianu 1.8 ((hce instanceof NEW) || (hce instanceof ANEW)) && 275 salcianu 1.8 getAllocatedType(hce).isInstanceOf(jl_Throwable)) { 276 salcianu 1.7 if(coalesced_excp == null) 277 salcianu 1.7 coalesced_excp = 278 salcianu 1.8 getNewNode 279 salcianu 1.8 (PANode.INSIDE, 280 salcianu 1.8 new GenType[] { new GenType(jl_Throwable, GenType.POLY)}); 281 salcianu 1.7 return coalesced_excp; 282 salcianu 1.7 } 283 salcianu 1.7 284 salcianu 1.1.2.1 PANode node = (PANode) code_nodes.get(hce); 285 salcianu 1.1.2.31 if((node == null) && make) { 286 salcianu 1.8 if(gts == null) 287 salcianu 1.8 gts = new GenType[] { get_code_node_type(hce) }; 288 salcianu 1.8 node = getNewNode(type, gts); 289 salcianu 1.1.2.26 code_nodes.put(hce, node); 290 salcianu 1.1.2.23 node2code.put(node, hce); 291 salcianu 1.1.2.29 292 salcianu 1.1.2.31 if(SHOW_NODE_CREATION) 293 salcianu 1.1.2.31 System.out.println("CREATED NODE " + node + " for " + 294 salcianu 1.6 Util.code2str(hce)); 295 salcianu 1.1.2.6 } 296 salcianu 1.1.2.1 return node; 297 salcianu 1.1.2.10 } 298 salcianu 1.1.2.10 299 salcianu 1.1.2.26 private final GenType get_code_node_type(HCodeElement hce) { 300 salcianu 1.1.2.26 Quad quad = (Quad) hce; 301 salcianu 1.1.2.26 302 salcianu 1.1.2.26 class GenTypeWrapper{ 303 salcianu 1.1.2.26 GenType gt = null; 304 salcianu 1.1.2.26 } 305 salcianu 1.1.2.26 final GenTypeWrapper retval = new GenTypeWrapper(); 306 salcianu 1.1.2.26 307 salcianu 1.1.2.26 quad.accept(new QuadVisitor() { 308 salcianu 1.1.2.26 public void visit(NEW q) { // INSIDE nodes 309 salcianu 1.1.2.26 retval.gt = new GenType(q.hclass(), GenType.MONO); 310 salcianu 1.1.2.26 } 311 salcianu 1.1.2.26 312 salcianu 1.1.2.26 public void visit(ANEW q) { // array INSIDE nodes 313 salcianu 1.1.2.26 retval.gt = new GenType(q.hclass(), GenType.MONO); 314 salcianu 1.1.2.26 } 315 salcianu 1.1.2.26 316 salcianu 1.1.2.26 public void visit(CALL q) { // RETURN nodes 317 salcianu 1.1.2.26 retval.gt = 318 salcianu 1.1.2.26 new GenType(q.method().getReturnType(), GenType.POLY); 319 salcianu 1.1.2.26 } 320 salcianu 1.1.2.26 321 salcianu 1.1.2.26 public void visit(GET q) { // LOAD nodes 322 salcianu 1.7 retval.gt = new GenType(q.field().getType(), GenType.POLY); 323 salcianu 1.1.2.26 } 324 salcianu 1.1.2.26 325 salcianu 1.1.2.26 public void visit(AGET q) { // LOAD nodes from array ops 326 salcianu 1.7 retval.gt = new GenType(q.type(), GenType.POLY); 327 salcianu 1.1.2.26 } 328 salcianu 1.1.2.26 329 salcianu 1.1.2.26 public void visit(Quad q) { 330 salcianu 1.1.2.26 // this should not happen 331 cananian 1.3.2.1 assert false : "Unknown quad " + q; 332 salcianu 1.1.2.26 } 333 salcianu 1.1.2.26 }); 334 salcianu 1.1.2.26 335 salcianu 1.1.2.26 return retval.gt; 336 salcianu 1.1.2.26 } 337 salcianu 1.1.2.26 338 salcianu 1.1.2.26 339 salcianu 1.1.2.15 // all the nodes are produced by this method. So, if we want them 340 salcianu 1.1.2.15 // to have a common characteristic, here is THE place to add things. 341 salcianu 1.1.2.26 static final PANode getNewNode(int type, GenType[] node_class) { 342 salcianu 1.9 PANode node = new PANode(type, node_class); 343 salcianu 1.9 344 salcianu 1.9 if(number2node == null) 345 salcianu 1.9 number2node = new Hashtable(); 346 salcianu 1.9 number2node.put(new Integer(node.number), node); 347 salcianu 1.9 348 salcianu 1.9 return node; 349 salcianu 1.1.2.26 } 350 salcianu 1.9 351 salcianu 1.9 private static Hashtable/*<Integer,PANode>*/ number2node; 352 salcianu 1.9 static PANode nodeForNumber(int number) { 353 salcianu 1.9 if(number2node == null) 354 salcianu 1.9 return null; 355 salcianu 1.9 return (PANode) number2node.get(new Integer(number)); 356 salcianu 1.9 } 357 salcianu 1.9 358 salcianu 1.1.2.26 359 salcianu 1.1.2.26 // default parameter for the node_class array. 360 salcianu 1.1.2.26 static final PANode getNewNode(int type) { 361 salcianu 1.1.2.26 return getNewNode(type, null); 362 salcianu 1.1.2.1 } 363 salcianu 1.1.2.26 364 salcianu 1.1.2.28 /** Returns the instruction that created <code>node</code>. */ 365 salcianu 1.1.2.28 public final HCodeElement node2Code(PANode node){ 366 salcianu 1.1.2.28 if(node == null) return null; 367 salcianu 1.1.2.28 return (HCodeElement) node2code.get(node); 368 salcianu 1.1.2.22 } 369 salcianu 1.1.2.32 370 salcianu 1.1.2.32 371 salcianu 1.1.2.32 /** Gets the type of an inside node. */ 372 salcianu 1.1.2.32 public final HClass getInsideNodeType(PANode node) { 373 cananian 1.3.2.1 assert node.type == PANode.INSIDE : "Not an inside node!"; 374 salcianu 1.1.2.32 PANode root = node.getRoot(); 375 salcianu 1.1.2.32 System.out.println("getInsideNodeType: " + root); 376 salcianu 1.1.2.32 HCodeElement hce = node2Code(root); 377 salcianu 1.6 System.out.println("getInsideNodeType: " + Util.code2str(hce)); 378 salcianu 1.1.2.32 return getAllocatedType(hce); 379 salcianu 1.1.2.32 } 380 salcianu 1.1.2.32 381 salcianu 1.1.2.32 382 salcianu 1.1.2.32 // get the type of the object allocated by the object creation site hce; 383 salcianu 1.1.2.32 // hce should be NEW or ANEW. 384 salcianu 1.1.2.32 public static HClass getAllocatedType(final HCodeElement hce){ 385 salcianu 1.1.2.32 if(hce instanceof NEW) 386 salcianu 1.1.2.32 return ((NEW) hce).hclass(); 387 salcianu 1.1.2.32 if(hce instanceof ANEW) 388 salcianu 1.1.2.32 return ((ANEW) hce).hclass(); 389 cananian 1.3.2.1 assert false : ("Not a NEW or ANEW: " + hce); 390 salcianu 1.1.2.32 return null; // should never happen 391 salcianu 1.1.2.32 } 392 salcianu 1.1.2.32 393 salcianu 1.1.2.22 394 salcianu 1.1.2.22 /** Modify the node2code mapping such that now node is associated 395 salcianu 1.1.2.22 with hce. */ 396 salcianu 1.1.2.22 public final void updateNode2Code(PANode node, HCodeElement hce){ 397 salcianu 1.1.2.22 // put the new one 398 salcianu 1.1.2.22 node2code.put(node, hce); 399 salcianu 1.1.2.6 } 400 salcianu 1.1.2.6 401 salcianu 1.1.2.6 /** Pretty-printer for debug purposes. */ 402 salcianu 1.1.2.5 public final String toString(){ 403 salcianu 1.1.2.5 StringBuffer buffer = new StringBuffer(); 404 salcianu 1.1.2.5 405 salcianu 1.1.2.5 buffer.append("PARAMETER NODES:\n"); 406 salcianu 1.1.2.12 Object[] mmethods = Debug.sortedSet(param_nodes.keySet()); 407 salcianu 1.1.2.12 for(int i = 0 ; i < mmethods.length ; i++){ 408 salcianu 1.1.2.12 MetaMethod mmethod = (MetaMethod) mmethods[i]; 409 salcianu 1.1.2.12 buffer.append(mmethod); 410 salcianu 1.1.2.12 // buffer.append(method.getDeclaringClass().getName()); 411 salcianu 1.1.2.12 // buffer.append("."); 412 salcianu 1.1.2.12 // buffer.append(method.getName()); 413 salcianu 1.1.2.5 buffer.append(":\t"); 414 salcianu 1.1.2.12 PANode[] nodes = getAllParams(mmethod); 415 salcianu 1.1.2.6 for(int j = 0 ; j < nodes.length ; j++){ 416 salcianu 1.1.2.6 buffer.append(nodes[j]); 417 salcianu 1.1.2.5 buffer.append(" "); 418 salcianu 1.1.2.5 } 419 salcianu 1.1.2.5 buffer.append("\n"); 420 salcianu 1.1.2.5 } 421 salcianu 1.1.2.5 422 salcianu 1.1.2.5 buffer.append("STATIC NODES:\n"); 423 salcianu 1.1.2.6 Object[] statics = Debug.sortedSet(static_nodes.keySet()); 424 salcianu 1.1.2.6 for(int i = 0; i < statics.length ; i++){ 425 salcianu 1.1.2.6 String class_name = (String) statics[i]; 426 salcianu 1.1.2.5 buffer.append(class_name); 427 salcianu 1.1.2.5 buffer.append(":\t"); 428 salcianu 1.1.2.5 buffer.append(getStaticNode(class_name)); 429 salcianu 1.1.2.5 buffer.append("\n"); 430 salcianu 1.1.2.5 } 431 salcianu 1.1.2.5 432 salcianu 1.1.2.5 buffer.append("CODE NODES:\n"); 433 salcianu 1.1.2.6 Object[] codes = Debug.sortedSet(code_nodes.keySet()); 434 salcianu 1.1.2.6 for(int i = 0 ; i < codes.length ; i++){ 435 salcianu 1.1.2.6 HCodeElement hce = (HCodeElement) codes[i]; 436 salcianu 1.1.2.5 Quad q = (Quad) hce; 437 salcianu 1.1.2.5 buffer.append((PANode)code_nodes.get(hce)); 438 salcianu 1.1.2.5 buffer.append("\t"); 439 salcianu 1.1.2.5 buffer.append(hce.getSourceFile()); 440 salcianu 1.1.2.5 buffer.append(":"); 441 salcianu 1.1.2.5 buffer.append(hce.getLineNumber()); 442 salcianu 1.1.2.5 buffer.append(" "); 443 salcianu 1.1.2.5 buffer.append(hce); 444 salcianu 1.1.2.5 buffer.append("\n"); 445 salcianu 1.1.2.5 } 446 salcianu 1.1.2.5 447 salcianu 1.1.2.9 codes = Debug.sortedSet(except_nodes.keySet()); 448 salcianu 1.1.2.9 for(int i = 0 ; i < codes.length ; i++){ 449 salcianu 1.1.2.9 HCodeElement hce = (HCodeElement) codes[i]; 450 salcianu 1.1.2.9 Quad q = (Quad) hce; 451 salcianu 1.1.2.9 buffer.append((PANode)except_nodes.get(hce)); 452 salcianu 1.1.2.9 buffer.append("\t"); 453 salcianu 1.1.2.9 buffer.append(hce.getSourceFile()); 454 salcianu 1.1.2.9 buffer.append(":"); 455 salcianu 1.1.2.9 buffer.append(hce.getLineNumber()); 456 salcianu 1.1.2.9 buffer.append(" "); 457 salcianu 1.1.2.9 buffer.append(hce); 458 salcianu 1.1.2.9 buffer.append("\n"); 459 salcianu 1.1.2.20 } 460 salcianu 1.1.2.20 461 salcianu 1.1.2.20 Object cfs[] = Debug.sortedSet(cf_nodes.keySet()); 462 salcianu 1.1.2.20 for(int i = 0; i < cfs.length; i++){ 463 salcianu 1.1.2.20 CFPair cfp = (CFPair) cfs[i]; 464 salcianu 1.1.2.20 HCodeElement hce = cfp.hce; 465 salcianu 1.1.2.20 buffer.append((PANode) cf_nodes.get(cfp) + "\t" + 466 salcianu 1.1.2.20 hce.getSourceFile() + ":" + hce.getLineNumber() + 467 salcianu 1.1.2.20 " " + cfp.hce + "\n"); 468 salcianu 1.1.2.9 } 469 salcianu 1.1.2.9 470 salcianu 1.1.2.5 return buffer.toString(); 471 salcianu 1.1.2.5 } 472 salcianu 1.1.2.5 473 salcianu 1.1.2.9 /** Prints some statistics. */ 474 salcianu 1.1.2.9 public void print_stats(){ 475 salcianu 1.1.2.11 int nb_total = PANode.count - 1; 476 salcianu 1.1.2.11 // the last -1 is for the InterThreadPA.THIS_THREAD conventional node 477 salcianu 1.1.2.9 int nb_excepts = except_nodes.size(); 478 salcianu 1.1.2.9 int nb_statics = static_nodes.size(); 479 salcianu 1.1.2.9 480 salcianu 1.1.2.9 int nb_insides = 0; 481 salcianu 1.1.2.9 int nb_loads = 0; 482 salcianu 1.1.2.9 int nb_returns = 0; 483 salcianu 1.7 int nb_consts = 1; // no other way of computing it 484 salcianu 1.7 int nb_nulls = 1; // no other way of computing it 485 salcianu 1.1.2.9 486 salcianu 1.7 for(Iterator it = code_nodes.keySet().iterator(); it.hasNext(); ) { 487 salcianu 1.1.2.9 PANode node = (PANode) code_nodes.get(it.next()); 488 salcianu 1.7 switch(node.type) { 489 salcianu 1.1.2.9 case PANode.INSIDE: 490 salcianu 1.1.2.9 nb_insides++; 491 salcianu 1.1.2.9 break; 492 salcianu 1.1.2.9 case PANode.LOAD: 493 salcianu 1.1.2.9 nb_loads++; 494 salcianu 1.1.2.9 break; 495 salcianu 1.1.2.9 case PANode.RETURN: 496 salcianu 1.1.2.9 nb_returns++; 497 salcianu 1.1.2.9 break; 498 salcianu 1.1.2.9 } 499 salcianu 1.1.2.9 } 500 salcianu 1.1.2.9 501 salcianu 1.1.2.9 int nb_params = 0; 502 salcianu 1.7 for(Iterator it = param_nodes.keySet().iterator(); it.hasNext(); ) 503 salcianu 1.1.2.9 nb_params += ((PANode[])(param_nodes.get(it.next()))).length; 504 salcianu 1.1.2.9 505 salcianu 1.1.2.11 int nb_roots = 506 salcianu 1.1.2.11 nb_insides + nb_returns + nb_excepts + 507 salcianu 1.7 nb_statics + nb_loads + nb_params + nb_consts + nb_nulls; 508 salcianu 1.1.2.11 509 salcianu 1.1.2.9 System.out.println("-NODE STATS-------------------------------"); 510 salcianu 1.1.2.11 System.out.println("INSIDE node(s) : " + nb_insides + " roots, " + 511 salcianu 1.7 (nb_total - nb_roots) + " specializations"); 512 salcianu 1.1.2.9 System.out.println("RETURN node(s) : " + nb_returns); 513 salcianu 1.1.2.9 System.out.println("EXCEPT node(s) : " + nb_excepts); 514 salcianu 1.1.2.9 System.out.println("STATIC node(s) : " + nb_statics); 515 salcianu 1.1.2.9 System.out.println("LOAD node(s) : " + nb_loads); 516 salcianu 1.1.2.9 System.out.println("PARAM node(s) : " + nb_params); 517 salcianu 1.7 System.out.println("CONST node(s) : " + nb_consts); 518 salcianu 1.7 System.out.println("NULL node(s) : " + nb_nulls); 519 salcianu 1.1.2.9 System.out.println("-------------------------"); 520 salcianu 1.1.2.9 System.out.println("TOTAL : " + nb_total); 521 salcianu 1.1.2.9 } 522 salcianu 1.1.2.9 523 salcianu 1.1.2.11 /** Nice looking info for debug purposes. */ 524 salcianu 1.1.2.11 public void show_specializations(){ 525 salcianu 1.1.2.11 System.out.println("-SPECIALIZATIONS--------------------------"); 526 salcianu 1.1.2.11 527 salcianu 1.1.2.11 Iterator it = code_nodes.keySet().iterator(); 528 salcianu 1.1.2.11 while(it.hasNext()){ 529 salcianu 1.1.2.11 PANode node = (PANode) code_nodes.get(it.next()); 530 salcianu 1.1.2.13 if(node.type == PANode.INSIDE){ 531 salcianu 1.1.2.13 System.out.print(node); 532 salcianu 1.1.2.13 HCodeElement hce = node2Code(node); 533 salcianu 1.1.2.16 System.out.println(" created at " + hce.getSourceFile() + 534 salcianu 1.1.2.16 ":" + hce.getLineNumber() + " " + hce); 535 salcianu 1.1.2.13 show_node_specs(node, 1); 536 salcianu 1.1.2.13 } 537 salcianu 1.1.2.11 } 538 salcianu 1.1.2.11 } 539 salcianu 1.1.2.11 540 salcianu 1.1.2.13 // shows the specializations (call site and thread specs) for node. 541 salcianu 1.1.2.13 private void show_node_specs(PANode node, int ident){ 542 salcianu 1.1.2.11 543 salcianu 1.1.2.19 if(PointerAnalysis.CALL_CONTEXT_SENSITIVE){ 544 cananian 1.10 for(Object entryO : node.getAllCSSpecs()){ 545 cananian 1.10 Map.Entry entry = (Map.Entry) entryO; 546 salcianu 1.1.2.13 CALL q = (CALL) entry.getKey(); 547 salcianu 1.1.2.13 PANode snode = (PANode) entry.getValue(); 548 salcianu 1.1.2.13 549 salcianu 1.1.2.13 for(int i = 0; i < ident ; i++) 550 salcianu 1.1.2.13 System.out.print(" "); 551 salcianu 1.1.2.13 System.out.print(snode); 552 salcianu 1.1.2.13 553 salcianu 1.1.2.13 System.out.print(" CallS from " + node + 554 salcianu 1.1.2.16 " at " + q.getSourceFile() + 555 salcianu 1.1.2.13 ":" + q.getLineNumber()); 556 salcianu 1.1.2.16 //if(PointerAnalysis.DETAILS2){ 557 salcianu 1.1.2.13 HMethod method = q.method(); 558 salcianu 1.1.2.13 System.out.print(" (CALL " + 559 salcianu 1.1.2.13 method.getDeclaringClass().getName()+"."+ 560 salcianu 1.1.2.13 method.getName() + ") "); 561 salcianu 1.1.2.16 //} 562 salcianu 1.1.2.13 System.out.println(); 563 salcianu 1.1.2.13 show_node_specs(snode, ident+1); 564 salcianu 1.1.2.13 } 565 salcianu 1.1.2.19 PANode bottom = node.getBottom(); 566 salcianu 1.1.2.19 if(bottom != null){ 567 salcianu 1.1.2.19 for(int i = 0; i < ident ; i++) 568 salcianu 1.1.2.19 System.out.print(" "); 569 salcianu 1.1.2.19 System.out.print(bottom); 570 salcianu 1.1.2.19 System.out.println("B"); 571 salcianu 1.1.2.19 } 572 salcianu 1.1.2.19 } 573 salcianu 1.1.2.11 574 salcianu 1.1.2.13 if(PointerAnalysis.THREAD_SENSITIVE) 575 cananian 1.10 for(Object entryO : node.getAllTSpecs()){ 576 cananian 1.10 Map.Entry entry = (Map.Entry) entryO; 577 salcianu 1.1.2.13 MetaMethod run = (MetaMethod) entry.getKey(); 578 salcianu 1.1.2.13 PANode snode = (PANode) entry.getValue(); 579 salcianu 1.1.2.13 580 salcianu 1.1.2.13 for(int i = 0; i < ident ; i++) 581 salcianu 1.1.2.13 System.out.print(" "); 582 salcianu 1.1.2.13 System.out.print(snode); 583 salcianu 1.1.2.13 System.out.println(" FTS from " + node + 584 salcianu 1.1.2.13 " for " + run); 585 salcianu 1.1.2.13 show_node_specs(snode, ident+1); 586 salcianu 1.1.2.13 } 587 salcianu 1.1.2.11 588 salcianu 1.1.2.13 if(PointerAnalysis.WEAKLY_THREAD_SENSITIVE){ 589 salcianu 1.1.2.14 PANode snode = node.getWTSpec(); 590 salcianu 1.1.2.13 if(snode != null){ 591 salcianu 1.1.2.13 for(int i = 0; i < ident ; i++) 592 salcianu 1.1.2.13 System.out.print(" "); 593 salcianu 1.1.2.13 System.out.print(snode); 594 salcianu 1.1.2.13 System.out.println(" WTS from " + node); 595 salcianu 1.1.2.13 show_node_specs(snode, ident+1); 596 salcianu 1.1.2.13 } 597 salcianu 1.1.2.11 } 598 salcianu 1.1.2.11 } 599 salcianu 1.1.2.11 600 cananian 1.2 }