1 cananian 1.1.2.1 // CloneImplementer.java, created Wed Jan 17 21:15:00 2001 by cananian 2 cananian 1.1.2.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.Analysis.Transactions; 5 cananian 1.1.2.1 6 cananian 1.7 import harpoon.Analysis.DefaultAllocationInformationMap; 7 cananian 1.1.2.1 import harpoon.ClassFile.DuplicateMemberException; 8 cananian 1.1.2.1 import harpoon.ClassFile.HClass; 9 cananian 1.1.2.1 import harpoon.ClassFile.HClassMutator; 10 cananian 1.1.2.1 import harpoon.ClassFile.HCode; 11 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory; 12 cananian 1.1.2.1 import harpoon.ClassFile.HField; 13 cananian 1.1.2.1 import harpoon.ClassFile.HMethod; 14 cananian 1.1.2.1 import harpoon.ClassFile.HMethodMutator; 15 cananian 1.1.2.1 import harpoon.ClassFile.Linker; 16 cananian 1.5 import harpoon.ClassFile.NoSuchClassException; 17 cananian 1.1.2.1 import harpoon.IR.Quads.AGET; 18 cananian 1.1.2.1 import harpoon.IR.Quads.ALENGTH; 19 cananian 1.1.2.1 import harpoon.IR.Quads.ANEW; 20 cananian 1.1.2.1 import harpoon.IR.Quads.ASET; 21 cananian 1.1.2.1 import harpoon.IR.Quads.CALL; 22 cananian 1.1.2.1 import harpoon.IR.Quads.CJMP; 23 cananian 1.1.2.1 import harpoon.IR.Quads.CONST; 24 cananian 1.1.2.1 import harpoon.IR.Quads.FOOTER; 25 cananian 1.1.2.1 import harpoon.IR.Quads.GET; 26 cananian 1.1.2.1 import harpoon.IR.Quads.HEADER; 27 cananian 1.1.2.1 import harpoon.IR.Quads.METHOD; 28 cananian 1.1.2.1 import harpoon.IR.Quads.NEW; 29 cananian 1.1.2.1 import harpoon.IR.Quads.OPER; 30 cananian 1.1.2.1 import harpoon.IR.Quads.PHI; 31 cananian 1.1.2.1 import harpoon.IR.Quads.Qop; 32 cananian 1.1.2.1 import harpoon.IR.Quads.Quad; 33 cananian 1.1.2.1 import harpoon.IR.Quads.QuadFactory; 34 cananian 1.1.2.1 import harpoon.IR.Quads.QuadSSI; 35 cananian 1.1.2.1 import harpoon.IR.Quads.RETURN; 36 cananian 1.1.2.1 import harpoon.IR.Quads.SET; 37 cananian 1.1.2.1 import harpoon.IR.Quads.THROW; 38 cananian 1.1.2.1 import harpoon.Temp.Temp; 39 cananian 1.1.2.1 import harpoon.Util.Util; 40 cananian 1.1.2.1 41 cananian 1.1.2.1 import java.lang.reflect.Modifier; 42 cananian 1.1.2.1 import java.util.ArrayList; 43 cananian 1.1.2.1 import java.util.Arrays; 44 cananian 1.1.2.1 import java.util.HashMap; 45 cananian 1.1.2.1 import java.util.Iterator; 46 cananian 1.1.2.1 import java.util.List; 47 cananian 1.1.2.1 import java.util.Map; 48 cananian 1.1.2.1 import java.util.Set; 49 cananian 1.1.2.1 /** 50 cananian 1.1.2.1 * <code>CloneImplementer</code> adds synthetic specialized implementations 51 cananian 1.1.2.1 * for all clone methods. This works around the incomplete field type 52 cananian 1.1.2.1 * information available to the runtime, as well as making clone() methods 53 cananian 1.1.2.1 * a little more amenable to standard analysis. (OK, the field type 54 cananian 1.1.2.1 * information isn't really *incomplete* as much as it is *inefficient to 55 cananian 1.1.2.1 * access* in the way we'd like to.) 56 cananian 1.1.2.1 * <p> 57 cananian 1.1.2.1 * Arguably, this class should belong in the 58 cananian 1.1.2.1 * <code>harpoon.Analysis.Quads</code> package, but we'll leave it 59 cananian 1.1.2.1 * here until someone other than the Transactions transformation 60 cananian 1.1.2.1 * needs it. 61 cananian 1.1.2.1 * <p> 62 cananian 1.1.2.1 * Implementation details: a specialized method called 63 cananian 1.1.2.1 * <code>$clone$()</code> is created in all known classes. The 64 cananian 1.1.2.1 * existing native <code>clone()</code> methods are made non-native 65 cananian 1.1.2.1 * and given implementations which redirect to the virtual 66 cananian 1.1.2.1 * <code>$clone$()</code> method. 67 cananian 1.1.2.1 * 68 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 69 cananian 1.8 * @version $Id: CloneImplementer.java,v 1.8 2004/02/08 03:20:25 cananian Exp $ 70 cananian 1.1.2.1 * @see harpoon.IR.Quads.CloneSynthesizer */ 71 cananian 1.1.2.1 public class CloneImplementer implements HCodeFactory, java.io.Serializable { 72 cananian 1.1.2.1 /** CONSTANTS */ 73 cananian 1.1.2.1 /** Name of usual "clone" method. */ 74 cananian 1.1.2.1 private final static String CLONE_NAME = "clone"; 75 cananian 1.1.2.1 /** Name of our synthesized "$clone$" method. */ 76 cananian 1.1.2.1 private final static String CLONEX_NAME = "$clone$"; 77 cananian 1.1.2.1 /** Descriptor of all clone methods. */ 78 cananian 1.1.2.1 private final static String CLONE_DESC = "()Ljava/lang/Object;"; 79 cananian 1.5 /** Descriptor of the GNU Classpath clone method. */ 80 cananian 1.5 private final static String GNUCP_CLONE_DESC = 81 cananian 1.5 "(Ljava/lang/Cloneable;)Ljava/lang/Object;"; 82 cananian 1.1.2.1 /** Modifiers of all standard clone methods. */ 83 cananian 1.1.2.1 private final static int CLONE_MODS = Modifier.PROTECTED; 84 cananian 1.5 /** Descriptor of java.lang.VMObject (GNU Classpath only) */ 85 cananian 1.5 private final static String GNUCP_VMOBJ_DESC = "Ljava/lang/VMObject;"; 86 cananian 1.1.2.1 /** Descriptor of java.lang.Object */ 87 cananian 1.1.2.1 private final static String OBJ_DESC = "Ljava/lang/Object;"; 88 cananian 1.1.2.1 /** Descriptor of Object[] */ 89 cananian 1.1.2.1 private final static String OBJARR_DESC = "[Ljava/lang/Object;"; 90 cananian 1.1.2.1 /** Parent code factory. */ 91 cananian 1.1.2.1 final HCodeFactory parent; 92 cananian 1.1.2.1 /** Representation cache. */ 93 cananian 1.6 final Map<HMethod,HCode> cache = new HashMap<HMethod,HCode>(); 94 cananian 1.1.2.1 95 cananian 1.1.2.1 /** Creates a <code>CloneImplementer</code> based on the 96 cananian 1.1.2.1 * given <code>HCodeFactory</code>, which must produce 97 cananian 1.1.2.1 * some QuadSSI form. */ 98 cananian 1.1.2.1 public CloneImplementer(HCodeFactory parent, Linker l, Set knownClasses) { 99 cananian 1.3.2.1 assert parent.getCodeName().equals(QuadSSI.codename); 100 cananian 1.1.2.1 this.parent = parent; 101 cananian 1.1.2.3 HClass HCobject = l.forName("java.lang.Object"); 102 cananian 1.1.2.3 HClass HCcloneable = l.forName("java.lang.Cloneable"); 103 cananian 1.1.2.1 /* okay, we need to add clone() methods to all of the knownClasses */ 104 cananian 1.8 for (Object hcO : knownClasses) { 105 cananian 1.8 HClass hc = (HClass) hcO; 106 cananian 1.1.2.2 if (hc.isPrimitive() || hc.isInterface()) continue; 107 cananian 1.1.2.3 if (!hc.equals(HCobject) && !hc.isInstanceOf(HCcloneable)) 108 cananian 1.1.2.3 continue; // non-cloneable objects get the default impl. 109 cananian 1.1.2.1 try { 110 cananian 1.1.2.1 HMethod hm = 111 cananian 1.1.2.1 hc.getMutator().addDeclaredMethod(CLONEX_NAME, CLONE_DESC); 112 cananian 1.1.2.1 hm.getMutator().setModifiers(CLONE_MODS); 113 cananian 1.1.2.1 hm.getMutator().setSynthetic(false); 114 cananian 1.1.2.1 } catch(DuplicateMemberException dme) { 115 cananian 1.3.2.1 assert false : "Can't create "+CLONEX_NAME+" in "+hc; 116 cananian 1.1.2.1 } 117 cananian 1.6 // for compatibility with other transformations that may 118 cananian 1.6 // add fields, cache away the declared fields of this class 119 cananian 1.6 for (; hc!=null; hc=hc.getSuperclass()) 120 cananian 1.6 declaredFieldMap.put(hc,Arrays.asList(hc.getDeclaredFields())); 121 cananian 1.1.2.1 } 122 cananian 1.1.2.1 /* 'un-native-ify' standard clone() methods (incl prim arrays) */ 123 cananian 1.1.2.1 String descs[] = new String[] { 124 cananian 1.1.2.1 "[Z", "[B", "[S", "[I", "[J", "[F", "[D", "[C", 125 cananian 1.1.2.1 OBJ_DESC, OBJARR_DESC 126 cananian 1.1.2.1 }; 127 cananian 1.1.2.1 for (int i=0; i<descs.length; i++) 128 cananian 1.1.2.1 l.forDescriptor(descs[i]).getMethod(CLONE_NAME, CLONE_DESC) 129 cananian 1.1.2.1 .getMutator().removeModifiers(Modifier.NATIVE); 130 cananian 1.5 // classpath compatibility. 131 cananian 1.5 try { 132 cananian 1.5 l.forDescriptor(GNUCP_VMOBJ_DESC) 133 cananian 1.5 .getMethod(CLONE_NAME, GNUCP_CLONE_DESC) 134 cananian 1.5 .getMutator().removeModifiers(Modifier.NATIVE); 135 cananian 1.5 } catch (NoSuchClassException e) { /* not using classpath */ } 136 cananian 1.1.2.1 /* done */ 137 cananian 1.1.2.1 } 138 cananian 1.1.2.1 public String getCodeName() { return parent.getCodeName(); } 139 cananian 1.1.2.1 public void clear(HMethod m) { cache.remove(m); parent.clear(m); } 140 cananian 1.1.2.1 public HCode convert(HMethod m) { 141 cananian 1.1.2.1 // check cache first 142 cananian 1.6 if (cache.containsKey(m)) 143 cananian 1.6 /* do nothing; cache already contains appropriate HCode */; 144 cananian 1.1.2.1 // now see if we need to synthesize a code for this method. 145 cananian 1.6 else if (m.getName().equals(CLONE_NAME) && 146 cananian 1.1.2.1 m.getDescriptor().equals(CLONE_DESC) && 147 cananian 1.1.2.1 (m.getDeclaringClass().getDescriptor().equals(OBJ_DESC) || 148 cananian 1.1.2.1 m.getDeclaringClass().isArray())) 149 cananian 1.6 cache.put(m, new CloneRedirectCode(m)); 150 cananian 1.5 // classpath compatibility: VMObject.clone() 151 cananian 1.6 else if (m.getName().equals(CLONE_NAME) && 152 cananian 1.5 m.getDescriptor().equals(GNUCP_CLONE_DESC) && 153 cananian 1.5 m.getDeclaringClass().getDescriptor().equals(GNUCP_VMOBJ_DESC)) 154 cananian 1.6 cache.put(m, new CloneRedirectCode(m)); 155 cananian 1.5 // okay, now implement $clone$ 156 cananian 1.6 else if (m.getName().equals(CLONEX_NAME) && 157 cananian 1.1.2.1 m.getDescriptor().equals(CLONE_DESC)) { 158 cananian 1.1.2.3 if (m.getDeclaringClass().getDescriptor().equals(OBJ_DESC)) 159 cananian 1.6 cache.put(m, new NotCloneableCode(m)); 160 cananian 1.1.2.3 else if (m.getDeclaringClass().isArray()) 161 cananian 1.6 cache.put(m, new ArrayCloneCode(m)); 162 cananian 1.1.2.1 else 163 cananian 1.6 cache.put(m, new ObjectCloneCode 164 cananian 1.6 (m, fields(m.getDeclaringClass()))); 165 cananian 1.6 } else // not synthetic: use parent's code. 166 cananian 1.6 cache.put(m, parent.convert(m)); 167 cananian 1.6 return cache.get(m); 168 cananian 1.1.2.1 } 169 cananian 1.1.2.2 /** this method just redirects to Object.$clone$() */ 170 cananian 1.1.2.1 private static class CloneRedirectCode extends QuadSSI { 171 cananian 1.1.2.1 CloneRedirectCode(HMethod m) { 172 cananian 1.1.2.1 super(m, null); 173 cananian 1.1.2.1 HMethod hm = m.getDeclaringClass().getLinker() 174 cananian 1.1.2.1 .forDescriptor(OBJ_DESC).getMethod(CLONEX_NAME, CLONE_DESC); 175 cananian 1.1.2.1 Temp thisT = new Temp(qf.tempFactory(), "this"); 176 cananian 1.1.2.1 Temp retvT = new Temp(qf.tempFactory(), "retval"); 177 cananian 1.1.2.1 Temp retxT = new Temp(qf.tempFactory(), "retex"); 178 cananian 1.1.2.1 Quad q0 = new HEADER(qf, null); 179 cananian 1.1.2.1 Quad q1 = new METHOD(qf, null, new Temp[] { thisT }, 1); 180 cananian 1.1.2.1 Quad q2 = new CALL(qf, null, hm, new Temp[] { thisT }, 181 cananian 1.1.2.1 retvT, retxT, true, true, new Temp[0]); 182 cananian 1.1.2.1 Quad q3 = new RETURN(qf, null, retvT); 183 cananian 1.1.2.1 Quad q4 = new THROW(qf, null, retxT); 184 cananian 1.1.2.1 Quad qF = new FOOTER(qf, null, 3); 185 cananian 1.1.2.1 Quad.addEdge(q0, 0, qF, 0); 186 cananian 1.1.2.2 Quad.addEdge(q0, 1, q1, 0); 187 cananian 1.1.2.1 Quad.addEdge(q1, 0, q2, 0); 188 cananian 1.1.2.1 Quad.addEdge(q2, 0, q3, 0); 189 cananian 1.1.2.1 Quad.addEdge(q2, 1, q4, 0); 190 cananian 1.1.2.1 Quad.addEdge(q3, 0, qF, 1); 191 cananian 1.1.2.1 Quad.addEdge(q4, 0, qF, 2); 192 cananian 1.1.2.1 // done! 193 cananian 1.1.2.1 this.quads = q0; 194 cananian 1.7 // no allocation in this method, so this next statement is 195 cananian 1.7 // actually redundant. 196 cananian 1.7 setAllocationInformation(new DefaultAllocationInformationMap()); 197 cananian 1.1.2.1 } 198 cananian 1.1.2.1 } 199 cananian 1.1.2.3 /** this method throws a CloneNotSupportedException */ 200 cananian 1.1.2.3 private static class NotCloneableCode extends QuadSSI { 201 cananian 1.1.2.3 NotCloneableCode(HMethod m) { 202 cananian 1.1.2.3 super(m, null); 203 cananian 1.1.2.3 HClass HCcnse = m.getDeclaringClass().getLinker() 204 cananian 1.1.2.3 .forName("java.lang.CloneNotSupportedException"); 205 cananian 1.1.2.3 HMethod hm = HCcnse.getConstructor(new HClass[0]); 206 cananian 1.1.2.3 Temp thisT = new Temp(qf.tempFactory(), "this"); 207 cananian 1.1.2.3 Temp excT0 = new Temp(qf.tempFactory(), "exc"); 208 cananian 1.1.2.3 Temp excT1 = new Temp(qf.tempFactory(), "exc"); 209 cananian 1.1.2.3 Temp excT2 = new Temp(qf.tempFactory(), "exc"); 210 cananian 1.1.2.3 Quad q0 = new HEADER(qf, null); 211 cananian 1.1.2.3 Quad q1 = new METHOD(qf, null, new Temp[] { thisT }, 1); 212 cananian 1.1.2.3 Quad q2 = new NEW(qf, null, excT0, HCcnse); 213 cananian 1.1.2.3 Quad q3 = new CALL(qf, null, hm, new Temp[] { excT0 }, null, 214 cananian 1.1.2.3 excT1, false, false, new Temp[0]); 215 cananian 1.1.2.3 Quad q4 = new PHI(qf, null, 216 cananian 1.1.2.3 new Temp[] { excT2 }, 217 cananian 1.1.2.3 new Temp[][] { new Temp[] { excT0, excT1 }}, 2); 218 cananian 1.1.2.3 Quad q5 = new THROW(qf, null, excT2); 219 cananian 1.1.2.3 Quad qF = new FOOTER(qf, null, 2); 220 cananian 1.1.2.3 Quad.addEdge(q0, 0, qF, 0); 221 cananian 1.1.2.3 Quad.addEdge(q0, 1, q1, 0); 222 cananian 1.1.2.3 Quad.addEdges(new Quad[] { q1, q2, q3, q4, q5 }); 223 cananian 1.1.2.3 Quad.addEdge(q3, 1, q4, 1); 224 cananian 1.1.2.3 Quad.addEdge(q5, 0, qF, 1); 225 cananian 1.1.2.3 // done! 226 cananian 1.1.2.3 this.quads = q0; 227 cananian 1.7 setAllocationInformation(new DefaultAllocationInformationMap()); 228 cananian 1.1.2.3 } 229 cananian 1.1.2.3 } 230 cananian 1.1.2.1 /* this method implements a specialized array clone operation */ 231 cananian 1.1.2.1 private static class ArrayCloneCode extends QuadSSI { 232 cananian 1.1.2.1 ArrayCloneCode(HMethod m) { 233 cananian 1.1.2.1 //XXX: this is actually pruned-ssi form, since we don't 234 cananian 1.1.2.1 // add phis and sigmas for thisT and objT. 235 cananian 1.1.2.1 super(m, null); 236 cananian 1.1.2.1 HClass hc = m.getDeclaringClass(); 237 cananian 1.1.2.1 HClass hcC = hc.getComponentType(); 238 cananian 1.1.2.1 Temp thisT = new Temp(qf.tempFactory(), "this"); 239 cananian 1.1.2.1 Temp lenT = new Temp(qf.tempFactory(), "length"); 240 cananian 1.1.2.1 Temp objT = new Temp(qf.tempFactory(), "result"); 241 cananian 1.1.2.1 Temp indT0 = new Temp(qf.tempFactory(), "index"); 242 cananian 1.1.2.1 Temp indT1 = new Temp(qf.tempFactory(), "index"); 243 cananian 1.1.2.1 Temp indT2 = new Temp(qf.tempFactory(), "index"); 244 cananian 1.1.2.1 Temp indT3 = new Temp(qf.tempFactory(), "index"); 245 cananian 1.1.2.1 Temp indT4 = new Temp(qf.tempFactory(), "index"); 246 cananian 1.1.2.1 Temp tstT = new Temp(qf.tempFactory(), "test"); 247 cananian 1.1.2.1 Temp tmpT = new Temp(qf.tempFactory(), "temp"); 248 cananian 1.1.2.1 Temp oneT = new Temp(qf.tempFactory(), "one"); 249 cananian 1.1.2.1 Quad q0 = new HEADER(qf, null); 250 cananian 1.1.2.1 Quad q1 = new METHOD(qf, null, new Temp[] { thisT }, 1); 251 cananian 1.1.2.1 Quad q2 = new ALENGTH(qf, null, lenT, thisT); 252 cananian 1.1.2.1 Quad q3 = new ANEW(qf, null, objT, hc, new Temp[] { lenT }); 253 cananian 1.1.2.1 // for (i=0; i<len; i++) ASET(objT, AGET(thisT, i)) 254 cananian 1.1.2.1 Quad q4 = new CONST(qf, null, indT0, new Integer(0), HClass.Int); 255 cananian 1.1.2.1 Quad q5 = new PHI(qf, null, // indT1 = phi(indT0, indT4) 256 cananian 1.1.2.1 new Temp[] { indT1 }, 257 cananian 1.1.2.1 new Temp[][] { new Temp[] { indT0, indT4 } }, 2); 258 cananian 1.1.2.1 Quad q6 = new OPER(qf, null, Qop.ICMPGT, tstT, 259 cananian 1.1.2.1 new Temp[] { lenT, indT1}); 260 cananian 1.1.2.1 Quad q7 = new CJMP(qf, null, tstT, // <indT2, indT3>=sigma(indT1) 261 cananian 1.1.2.1 new Temp[][] { new Temp[] { indT2, indT3 } }, 262 cananian 1.1.2.1 new Temp[] { indT1 }); 263 cananian 1.1.2.1 Quad q8 = new AGET(qf, null, tmpT, thisT, indT3, hcC); 264 cananian 1.1.2.1 Quad q9 = new ASET(qf, null, objT, indT3, tmpT, hcC); 265 cananian 1.1.2.1 Quad qA = new CONST(qf, null, oneT, new Integer(1), HClass.Int); 266 cananian 1.1.2.1 Quad qB = new OPER(qf, null, Qop.IADD, indT4, 267 cananian 1.1.2.1 new Temp[] { indT3, oneT }); 268 cananian 1.1.2.1 Quad qC = new RETURN(qf, null, objT); 269 cananian 1.1.2.1 Quad qF = new FOOTER(qf, null, 2); 270 cananian 1.1.2.1 Quad.addEdge(q0, 0, qF, 0); 271 cananian 1.1.2.2 Quad.addEdge(q0, 1, q1, 0); 272 cananian 1.1.2.1 Quad.addEdges(new Quad[] { q1, q2, q3, q4, q5, q6, q7, qC }); 273 cananian 1.1.2.1 Quad.addEdge(q7, 1, q8, 0); 274 cananian 1.1.2.1 Quad.addEdge(qC, 0, qF, 1); 275 cananian 1.1.2.1 Quad.addEdges(new Quad[] { q8, q9, qA, qB }); 276 cananian 1.1.2.1 Quad.addEdge(qB, 0, q5, 1); 277 cananian 1.1.2.1 // done! 278 cananian 1.1.2.1 this.quads = q0; 279 cananian 1.7 setAllocationInformation(new DefaultAllocationInformationMap()); 280 cananian 1.1.2.1 } 281 cananian 1.1.2.1 } 282 cananian 1.1.2.1 /* this method implements a specialized object clone operation */ 283 cananian 1.1.2.1 private static class ObjectCloneCode extends QuadSSI { 284 cananian 1.6 ObjectCloneCode(HMethod m, List<HField> fields) { 285 cananian 1.1.2.1 super(m, null); 286 cananian 1.1.2.1 HClass hc = m.getDeclaringClass(); 287 cananian 1.1.2.1 Temp thisT = new Temp(qf.tempFactory()); 288 cananian 1.1.2.1 Temp objT = new Temp(qf.tempFactory()); 289 cananian 1.1.2.1 Quad q0 = new HEADER(qf, null); 290 cananian 1.1.2.1 Quad q1 = new METHOD(qf, null, new Temp[] { thisT }, 1); 291 cananian 1.1.2.1 Quad q2 = new NEW(qf, null, objT, hc); 292 cananian 1.1.2.1 Quad.addEdge(q0, 1, q1, 0); 293 cananian 1.1.2.1 Quad.addEdge(q1, 0, q2, 0); 294 cananian 1.1.2.1 Quad qq = q2; 295 cananian 1.8 for (HField hf : fields) { 296 cananian 1.1.2.1 Temp tT = new Temp(qf.tempFactory()); 297 cananian 1.1.2.1 Quad q3 = new GET(qf, null, tT, hf, thisT); 298 cananian 1.1.2.1 Quad q4 = new SET(qf, null, hf, objT, tT); 299 cananian 1.1.2.1 Quad.addEdges(new Quad[] { qq, q3, q4 }); 300 cananian 1.1.2.1 qq = q4; 301 cananian 1.1.2.1 } 302 cananian 1.1.2.3 Quad q5 = new RETURN(qf, null, objT); 303 cananian 1.1.2.1 Quad qF = new FOOTER(qf, null, 2); 304 cananian 1.1.2.1 Quad.addEdge(qq, 0, q5, 0); 305 cananian 1.1.2.1 Quad.addEdge(q5, 0, qF, 1); 306 cananian 1.1.2.1 Quad.addEdge(q0, 0, qF, 0); 307 cananian 1.1.2.1 // done! 308 cananian 1.1.2.1 this.quads = q0; 309 cananian 1.7 setAllocationInformation(new DefaultAllocationInformationMap()); 310 cananian 1.1.2.1 } 311 cananian 1.1.2.1 } 312 cananian 1.6 /** Return a <code>List</code> of all fields (including 313 cananian 1.6 private fields of superclasses) belonging to 314 cananian 1.6 <code>HClass</code> <code>hc</code>. */ 315 cananian 1.6 private List<HField> fields(HClass hc) { 316 cananian 1.6 List<HField> l = new ArrayList<HField>(hc.getFields().length); 317 cananian 1.6 for (; hc!=null; hc=hc.getSuperclass()) 318 cananian 1.6 l.addAll(0, declaredFieldMap.get(hc)); 319 cananian 1.6 // filter out static fields. 320 cananian 1.6 for (Iterator<HField> it=l.iterator(); it.hasNext(); ) 321 cananian 1.6 if (it.next().isStatic()) 322 cananian 1.6 it.remove(); 323 cananian 1.6 // done. 324 cananian 1.6 return l; 325 cananian 1.6 } 326 cananian 1.6 private final Map<HClass,List<HField>> declaredFieldMap = 327 cananian 1.6 new HashMap<HClass,List<HField>>(); 328 cananian 1.2 }