1 salcianu 1.1.2.1 // PASync.java, created Wed Mar 29 12:38:44 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.PointerAnalysis; 5 salcianu 1.1.2.1 6 salcianu 1.1.2.1 import java.util.Map; 7 salcianu 1.1.2.1 import java.util.Set; 8 salcianu 1.1.2.1 import java.util.HashSet; 9 salcianu 1.1.2.1 import java.util.Iterator; 10 salcianu 1.1.2.1 import java.util.Collections; 11 salcianu 1.1.2.1 12 salcianu 1.1.2.1 import harpoon.ClassFile.HCodeElement; 13 salcianu 1.1.2.1 import harpoon.IR.Quads.CALL; 14 salcianu 1.1.2.1 import harpoon.Analysis.MetaMethods.MetaMethod; 15 salcianu 1.1.2.4 import harpoon.Util.DataStructs.Relation; 16 salcianu 1.1.2.1 17 salcianu 1.1.2.1 /** 18 salcianu 1.1.2.1 * <code>PASync</code> models a <code>sync</code> action. 19 salcianu 1.1.2.1 * 20 cananian 1.1.2.7 * @author Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu> 21 cananian 1.3 * @version $Id: PASync.java,v 1.3 2004/02/08 03:20:03 cananian Exp $ 22 salcianu 1.1.2.1 */ 23 salcianu 1.1.2.5 public class PASync implements java.io.Serializable { 24 salcianu 1.1.2.1 /** The node on which the <code>sync</code> is performed on. */ 25 salcianu 1.1.2.1 public PANode n; 26 salcianu 1.1.2.1 /** The thread which performs the <code>sync</code>. */ 27 salcianu 1.1.2.1 public PANode nt; 28 salcianu 1.1.2.1 /** The instruction which performs the <code>sync</code>. */ 29 salcianu 1.1.2.1 public HCodeElement hce; 30 salcianu 1.1.2.1 31 salcianu 1.1.2.1 /** The depth of the call-path specialization chain; if 0, the 32 salcianu 1.1.2.1 <code>sync</code> took place in the current method. */ 33 salcianu 1.1.2.1 public int depth; 34 salcianu 1.1.2.1 /** The call chain that specializes this action. Its size is equal 35 salcianu 1.1.2.1 to <code>depth</code>. To cope with the recursive methods, this 36 salcianu 1.1.2.1 is just the last part of the call-path, containing up to 37 salcianu 1.1.2.1 <code>PointerAnalysis.MAX_SPEC_DEPTH</code> elements: every chain 38 salcianu 1.1.2.1 shorter than that limit is exact, the rest are just approximations. */ 39 salcianu 1.1.2.1 public ListCell call_path; 40 salcianu 1.1.2.1 41 salcianu 1.1.2.1 /** If <code>this</code> action is the thread specialization of another 42 salcianu 1.1.2.1 action, this is the run method of the thread which does this action. */ 43 salcianu 1.1.2.1 public MetaMethod wtspec_run; 44 salcianu 1.1.2.1 45 salcianu 1.1.2.1 /** Creates a <code>PASync</code>. */ 46 salcianu 1.1.2.1 public PASync(PANode n, PANode nt, HCodeElement hce) { 47 salcianu 1.1.2.1 this(n, nt, hce, 0, null, null); 48 salcianu 1.1.2.1 } 49 salcianu 1.1.2.1 50 salcianu 1.1.2.1 /** Private constructor. */ 51 salcianu 1.1.2.1 private PASync(PANode n, PANode nt, HCodeElement hce, int depth, 52 salcianu 1.1.2.1 ListCell call_path, MetaMethod wtspec_run){ 53 salcianu 1.1.2.1 this.n = n; 54 salcianu 1.1.2.1 this.nt = nt; 55 salcianu 1.1.2.1 this.hce = hce; 56 salcianu 1.1.2.1 this.depth = depth; 57 salcianu 1.1.2.1 this.call_path = call_path; 58 salcianu 1.1.2.1 this.wtspec_run = wtspec_run; 59 salcianu 1.1.2.1 } 60 salcianu 1.1.2.1 61 salcianu 1.1.2.2 /** Checks whether <code>node</code> can still be specialized. 62 salcianu 1.1.2.2 (is an INSIDE node that is not bottom) */ 63 salcianu 1.1.2.2 private boolean ableToBeSpecialized(PANode node){ 64 salcianu 1.1.2.2 return 65 salcianu 1.1.2.2 (node != ActionRepository.THIS_THREAD) && 66 salcianu 1.1.2.2 (node.type == PANode.INSIDE) && !node.isBottom(); 67 salcianu 1.1.2.2 } 68 salcianu 1.1.2.2 69 salcianu 1.1.2.1 /** Specializes this action for a specific call site. The argument is 70 salcianu 1.1.2.1 supposed to be a <code>CALL</code>. It is added at the end of the 71 salcianu 1.1.2.1 call chain. The new, specialized action is returned.<br> 72 salcianu 1.1.2.1 <b>Note:</b> If the depth of this action is too big, no specialization 73 salcianu 1.1.2.1 takes place; instead, <code>this</code> object is returned. */ 74 salcianu 1.1.2.1 public PASync csSpecialize(final Map map, final CALL call){ 75 salcianu 1.1.2.2 if(depth >= PointerAnalysis.MAX_SPEC_DEPTH){ 76 salcianu 1.1.2.2 if(!(ableToBeSpecialized(n) || ableToBeSpecialized(nt))) 77 salcianu 1.1.2.2 return this; 78 salcianu 1.1.2.2 } 79 salcianu 1.1.2.2 80 salcianu 1.1.2.3 ///// System.out.println("DEPTH: " + (depth + 1) + " < sync , " + n + 81 salcianu 1.1.2.3 ///// " , " + nt + " >"); 82 salcianu 1.1.2.1 83 salcianu 1.1.2.1 return 84 salcianu 1.1.2.1 new PASync(PANode.translate(n, map), 85 salcianu 1.1.2.1 PANode.translate(nt, map), 86 salcianu 1.1.2.1 hce, 87 salcianu 1.1.2.1 depth + 1, 88 salcianu 1.1.2.1 new ListCell(call, call_path), 89 salcianu 1.1.2.1 null); 90 salcianu 1.1.2.1 } 91 salcianu 1.1.2.1 92 salcianu 1.1.2.1 /** Returns the image of <code>this</code> <code>sync</code> action 93 salcianu 1.1.2.1 projected through the relation <code>mu</code>. */ 94 salcianu 1.1.2.1 public Set project(Relation mu){ 95 salcianu 1.1.2.4 Set set_n = mu.getValues(n); 96 salcianu 1.1.2.4 Set set_nt = mu.getValues(nt); 97 salcianu 1.1.2.1 if(set_n.isEmpty() || set_nt.isEmpty()) 98 salcianu 1.1.2.1 return Collections.EMPTY_SET; 99 salcianu 1.1.2.1 100 salcianu 1.1.2.1 // save some space by avoid to allocate the same stuff once again 101 salcianu 1.1.2.1 if((set_n.size() == 1) && (set_nt.size() == 1) && 102 salcianu 1.1.2.1 set_n.contains(n) && set_nt.contains(nt)) 103 salcianu 1.1.2.1 return Collections.singleton(this); 104 salcianu 1.1.2.1 105 salcianu 1.1.2.1 Set retval = new HashSet(); 106 salcianu 1.1.2.1 107 cananian 1.3 for(Object new_nO : set_n){ 108 cananian 1.3 PANode new_n = (PANode) new_nO; 109 cananian 1.3 for(Object new_ntO : set_nt){ 110 cananian 1.3 PANode new_nt = (PANode) new_ntO; 111 salcianu 1.1.2.1 retval.add(new PASync(new_n, new_nt, hce, depth, 112 salcianu 1.1.2.1 call_path, wtspec_run)); 113 salcianu 1.1.2.1 } 114 salcianu 1.1.2.1 } 115 salcianu 1.1.2.1 116 salcianu 1.1.2.1 return retval; 117 salcianu 1.1.2.1 } 118 salcianu 1.1.2.1 119 salcianu 1.1.2.1 /** Checks whether this action is a calling context specialization of 120 salcianu 1.1.2.1 some other one. */ 121 salcianu 1.1.2.1 public boolean isCSSpec(){ 122 salcianu 1.1.2.1 return depth != 0; 123 salcianu 1.1.2.1 } 124 salcianu 1.1.2.1 125 salcianu 1.1.2.1 /** Does the thread-specialization of <code>this</code> action. */ 126 salcianu 1.1.2.1 public PASync tSpecialize(final Map map, final MetaMethod run){ 127 salcianu 1.1.2.1 return 128 salcianu 1.1.2.1 new PASync(PANode.translate(n, map), 129 salcianu 1.1.2.1 PANode.translate(nt, map), 130 salcianu 1.1.2.1 hce, 131 salcianu 1.1.2.1 depth, 132 salcianu 1.1.2.1 call_path, 133 salcianu 1.1.2.1 run); 134 salcianu 1.1.2.1 } 135 salcianu 1.1.2.1 136 salcianu 1.1.2.1 /** Checks whether this action is a thread specialization of some 137 salcianu 1.1.2.1 other one. */ 138 salcianu 1.1.2.1 public boolean isTSpec(){ 139 salcianu 1.1.2.1 return wtspec_run != null; 140 salcianu 1.1.2.1 } 141 salcianu 1.1.2.1 142 salcianu 1.1.2.1 /** Checks the equality of this object with another one. */ 143 salcianu 1.1.2.1 public boolean equals(Object obj){ 144 salcianu 1.1.2.1 if(obj == this) return true; 145 salcianu 1.1.2.1 PASync s2 = (PASync) obj; 146 salcianu 1.1.2.1 return 147 salcianu 1.1.2.1 n.equals(s2.n) && 148 salcianu 1.1.2.1 nt.equals(s2.nt) && 149 salcianu 1.1.2.1 (depth == s2.depth) && 150 salcianu 1.1.2.1 hce.equals(s2.hce) && 151 salcianu 1.1.2.1 MetaMethod.identical(wtspec_run, s2.wtspec_run) && 152 salcianu 1.1.2.1 ListCell.identical(call_path, s2.call_path); 153 salcianu 1.1.2.1 } 154 salcianu 1.1.2.1 155 salcianu 1.1.2.1 /** Cache for the hash code. */ 156 salcianu 1.1.2.1 private int hash = -1; 157 salcianu 1.1.2.1 public int hashCode(){ 158 salcianu 1.1.2.1 if(hash == -1) 159 salcianu 1.1.2.1 // this should be variate enough 160 salcianu 1.1.2.1 hash = n.hashCode() + nt.hashCode() + depth + hce.hashCode(); 161 salcianu 1.1.2.1 return hash; 162 salcianu 1.1.2.1 } 163 salcianu 1.1.2.1 164 salcianu 1.1.2.1 /** String representation for debug purposes. */ 165 salcianu 1.1.2.1 public String toString(){ 166 salcianu 1.1.2.1 StringBuffer buffer = new StringBuffer(); 167 salcianu 1.1.2.1 buffer.append("< sync, " + n + 168 salcianu 1.1.2.1 (nt != ActionRepository.THIS_THREAD?(", " + nt):"") + 169 salcianu 1.1.2.1 " > "); 170 salcianu 1.1.2.1 if(isTSpec()) 171 salcianu 1.1.2.1 buffer.append(" <-TS-"); 172 salcianu 1.1.2.1 for(ListCell lc = call_path; lc != null; lc = lc.next) 173 salcianu 1.1.2.1 buffer.append(" <- " + (CALL) lc.info + " - "); 174 salcianu 1.1.2.1 175 salcianu 1.1.2.6 if(hce == null) 176 salcianu 1.1.2.6 buffer.append(" {(sync in native code)}"); 177 salcianu 1.1.2.6 else 178 salcianu 1.1.2.6 buffer.append(" {" + hce.getSourceFile() + ":" + 179 salcianu 1.1.2.6 hce.getLineNumber() + " " + hce + "}"); 180 salcianu 1.1.2.1 181 salcianu 1.1.2.1 return buffer.toString(); 182 salcianu 1.1.2.1 } 183 cananian 1.2 }