1 kkz      1.1.2.1  // GCInfo.java, created Wed Jan 26 09:40:41 2000 by kkz
  2 cananian 1.1.2.12 // Copyright (C) 2000 Karen K. Zee <kkz@alum.mit.edu>
  3 kkz      1.1.2.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 kkz      1.1.2.1  package harpoon.Backend.Generic;
  5 kkz      1.1.2.1  
  6 kkz      1.1.2.1  import harpoon.Analysis.Instr.RegAlloc.IntermediateCodeFactory;
  7 kkz      1.1.2.1  import harpoon.Backend.Generic.Frame;
  8 kkz      1.1.2.1  import harpoon.Backend.Generic.RegFileInfo.CommonLoc;
  9 kkz      1.1.2.1  import harpoon.Backend.Generic.RegFileInfo.MachineRegLoc;
 10 kkz      1.1.2.1  import harpoon.Backend.Generic.RegFileInfo.StackOffsetLoc;
 11 kkz      1.1.2.5  import harpoon.ClassFile.HClass;
 12 kkz      1.1.2.1  import harpoon.ClassFile.HCodeFactory;
 13 kkz      1.1.2.1  import harpoon.ClassFile.HMethod;
 14 kkz      1.1.2.1  import harpoon.IR.Assem.Instr;
 15 kkz      1.1.2.1  import harpoon.Temp.Label;
 16 kkz      1.1.2.1  import harpoon.Util.Util;
 17 kkz      1.1.2.1  
 18 kkz      1.1.2.1  import java.util.ArrayList;
 19 kkz      1.1.2.9  import java.util.Collections;
 20 kkz      1.1.2.1  import java.util.Iterator;
 21 kkz      1.1.2.1  import java.util.List;
 22 kkz      1.1.2.1  import java.util.HashMap;
 23 kkz      1.1.2.10 import java.util.HashSet;
 24 kkz      1.1.2.1  import java.util.Map;
 25 kkz      1.1.2.1  import java.util.Set;
 26 kkz      1.1.2.1  
 27 kkz      1.1.2.1  /**
 28 kkz      1.1.2.1   * A <code>GCInfo</code> object collects data needed for
 29 kkz      1.1.2.1   * garbage collection and makes necessary annotations to
 30 kkz      1.1.2.1   * the instruction stream.
 31 kkz      1.1.2.1   * 
 32 cananian 1.1.2.12  * @author  Karen K. Zee <kkz@alum.mit.edu>
 33 cananian 1.5       * @version $Id: GCInfo.java,v 1.5 2004/02/08 03:20:50 cananian Exp $
 34 kkz      1.1.2.1   */
 35 kkz      1.1.2.1  public abstract class GCInfo {
 36 kkz      1.1.2.1      /** Creates an <code>IntermediateCodeFactory</code> that
 37 kkz      1.1.2.1          prepares the code for garbage collection.
 38 kkz      1.1.2.1          <BR> <B>requires:</B> The <code>parentFactory</code>
 39 kkz      1.1.2.5               must produce code in <code>Instr</code> form.
 40 kkz      1.1.2.1          <BR> <B>effects:</B> Returns an 
 41 kkz      1.1.2.1               <code>IntermediateCodeFactory</code> that modifies
 42 kkz      1.1.2.1               the code as needed for a particular garbage
 43 kkz      1.1.2.1               collection scheme and stores the necessary
 44 kkz      1.1.2.1               garbage collection data in the <code>GCInfo</code>
 45 kkz      1.1.2.1               object.
 46 kkz      1.1.2.1       */
 47 kkz      1.1.2.1      public abstract IntermediateCodeFactory 
 48 kkz      1.1.2.1          codeFactory(IntermediateCodeFactory parentFactory, Frame frame);
 49 kkz      1.1.2.1      /** Returns an ordered <code>List</code> of the
 50 kkz      1.1.2.2          <code>GCPoint</code>s in a given <code>HMethod</code>.
 51 kkz      1.1.2.2          Returns <code>null</code> if the <code>HMethod</code>
 52 kkz      1.1.2.2          has not been evaluated for garbage collection purposes.
 53 kkz      1.1.2.2          Returns an empty <code>List</code> if the 
 54 kkz      1.1.2.2          <code>HMethod</code> has been evaluated and has been
 55 kkz      1.1.2.2          found to not contain any GC points.
 56 kkz      1.1.2.2      */
 57 kkz      1.1.2.5      public abstract List gcPoints(HMethod hm);
 58 kkz      1.1.2.5      /** Returns a <code>List</code> of <code>HMethod</code>s
 59 kkz      1.1.2.5          with the following properties:
 60 kkz      1.1.2.5          - The declaring class of the <code>HMethod</code> is
 61 kkz      1.1.2.5          <code>HClass</code>.
 62 kkz      1.1.2.5          - The <code>convert</code> method of the 
 63 kkz      1.1.2.5          <code>IntermediateCodeFactory</code> has been invoked
 64 kkz      1.1.2.5          on all the <code>HMethod</code>s in the <code>List</code>. 
 65 kkz      1.1.2.5          The <code>IntermediateCodeFactory</code> referred
 66 kkz      1.1.2.5          to here is the one returned by the <code>codeFactory</code>
 67 kkz      1.1.2.5          method of <code>this</code>. Returns null if the given 
 68 kkz      1.1.2.5          <code>HClass</code> does not declare any methods on which 
 69 kkz      1.1.2.5          <code>convert</code> has been invoked.
 70 kkz      1.1.2.5          - The <code>HMethod</code>s are ordered according to the
 71 kkz      1.1.2.5          order in which the <code>convert</code> method was invoked.
 72 kkz      1.1.2.5      */
 73 kkz      1.1.2.5      public abstract List getOrderedMethods(HClass hc);
 74 kkz      1.1.2.1      /** A <code>GCPoint</code> contains information about all
 75 kkz      1.1.2.1       *  the live objects that the garbage collector needs to
 76 kkz      1.1.2.1       *  add to the root set at a particular GC point.
 77 kkz      1.1.2.1       */
 78 kkz      1.1.2.1      public static class GCPoint {
 79 kkz      1.1.2.1          protected Instr gcPoint;
 80 kkz      1.1.2.1          protected Label label;
 81 kkz      1.1.2.6          protected Map regDerivations;
 82 kkz      1.1.2.6          protected Map stackDerivations;
 83 kkz      1.1.2.1          protected Set liveStackOffsetLocs;
 84 kkz      1.1.2.1          protected Set liveMachineRegLocs;
 85 kkz      1.1.2.9          protected Map calleeSaved;
 86 kkz      1.1.2.1          /** Creates a <code>GCPoint</code> object 
 87 kkz      1.1.2.1              @param label
 88 kkz      1.1.2.1                     the <code>Label</code> identifying
 89 kkz      1.1.2.1                     the <code>gcPoint</code>
 90 kkz      1.1.2.1              @param liveDerivations
 91 kkz      1.1.2.6                     a <code>Map</code> of pointer locations as
 92 kkz      1.1.2.5                     <code>Set</code>s of <code>CommonLoc</code>s to 
 93 kkz      1.1.2.5                     the corresponding derivation information as 
 94 kkz      1.1.2.5                     <code>DLoc</code>s
 95 kkz      1.1.2.1              @param locations
 96 kkz      1.1.2.5                     a <code>Set</code> of <code>CommonLoc</code>s that
 97 kkz      1.1.2.7                     represent live pointers at the given GC point
 98 kkz      1.1.2.7              @param calleeSaved
 99 kkz      1.1.2.9                     a <code>Map</code> of the callee-saved
100 kkz      1.1.2.9                     <code>BackendDerivation.Register</code>s to
101 kkz      1.1.2.10                    the <code>WrappedStackOffsetLoc</code>s 
102 kkz      1.1.2.9                     where its contents has been stored
103 kkz      1.1.2.5          */
104 kkz      1.1.2.1          public GCPoint(Instr gcPoint, Label label, Map liveDerivations,
105 kkz      1.1.2.9                         Set locations, Map calleeSaved) {
106 kkz      1.1.2.1              this.gcPoint = gcPoint;
107 kkz      1.1.2.1              this.label = label;
108 kkz      1.1.2.7              this.calleeSaved = calleeSaved;
109 kkz      1.1.2.10             this.liveStackOffsetLocs = new HashSet();
110 kkz      1.1.2.10             this.liveMachineRegLocs = new HashSet();
111 kkz      1.1.2.6              filter(liveDerivations);
112 kkz      1.1.2.1              filter(locations);
113 kkz      1.1.2.1          }
114 kkz      1.1.2.6          // Sorts derivations by location type of derived pointer
115 kkz      1.1.2.6          private void filter(Map derivations) {
116 kkz      1.1.2.6              regDerivations = new HashMap();
117 kkz      1.1.2.6              stackDerivations = new HashMap();
118 cananian 1.5                  for(Object keyO : derivations.keySet()) {
119 cananian 1.5                      Set key = (Set) keyO;
120 kkz      1.1.2.6                  DLoc derivation = (DLoc)derivations.get(key);
121 cananian 1.5                      for(Object locO : key) {
122 cananian 1.5                          CommonLoc loc = (CommonLoc) locO;
123 kkz      1.1.2.6                      switch(loc.kind()) {
124 kkz      1.1.2.6                      case StackOffsetLoc.KIND:
125 kkz      1.1.2.10                         WrappedStackOffsetLoc wsol =
126 kkz      1.1.2.10                             new WrappedStackOffsetLoc((StackOffsetLoc)loc);
127 kkz      1.1.2.10                         stackDerivations.put(wsol, derivation); 
128 kkz      1.1.2.10                         break;
129 kkz      1.1.2.6                      case MachineRegLoc.KIND:
130 kkz      1.1.2.10                         WrappedMachineRegLoc wmrl = 
131 kkz      1.1.2.10                             new WrappedMachineRegLoc((MachineRegLoc)loc);
132 kkz      1.1.2.10                         regDerivations.put(wmrl, derivation); 
133 kkz      1.1.2.10                         break;
134 kkz      1.1.2.6                      default:
135 cananian 1.3.2.1                          assert false;               
136 kkz      1.1.2.6                      }
137 kkz      1.1.2.6                  }
138 kkz      1.1.2.6              }
139 kkz      1.1.2.6          }
140 kkz      1.1.2.1          // Sorts the various locations by type
141 kkz      1.1.2.1          private void filter(Set locations) {
142 cananian 1.5                  for(Object locO : locations) {
143 cananian 1.5                      CommonLoc loc = (CommonLoc) locO;
144 kkz      1.1.2.5                  switch(loc.kind()) {
145 kkz      1.1.2.5                  case StackOffsetLoc.KIND:
146 kkz      1.1.2.10                     WrappedStackOffsetLoc wsol =
147 kkz      1.1.2.10                         new WrappedStackOffsetLoc((StackOffsetLoc)loc);
148 kkz      1.1.2.10                     liveStackOffsetLocs.add(wsol); 
149 kkz      1.1.2.10                     break;
150 kkz      1.1.2.5                  case MachineRegLoc.KIND:
151 kkz      1.1.2.10                     WrappedMachineRegLoc wmrl = 
152 kkz      1.1.2.10                         new WrappedMachineRegLoc((MachineRegLoc)loc);
153 kkz      1.1.2.10                     liveMachineRegLocs.add(wmrl); 
154 kkz      1.1.2.10                     break;
155 kkz      1.1.2.5                  default:
156 cananian 1.3.2.1                      assert false;
157 kkz      1.1.2.1                  }
158 kkz      1.1.2.1              }
159 kkz      1.1.2.1          }
160 kkz      1.1.2.6          /** Returns the <code>Label</code> identifying the GC point */
161 kkz      1.1.2.1          public Label label() { return label; }
162 kkz      1.1.2.9          /** Returns an unmodifiable <code>Map</code> of live derived 
163 kkz      1.1.2.10             pointers in <code>WrappedMachineRegLoc</code>s to the 
164 kkz      1.1.2.10             derivation information in the form of <code>DLoc</code>s 
165 kkz      1.1.2.10             for that GC point */
166 kkz      1.1.2.9          public Map regDerivations() { 
167 kkz      1.1.2.9              return Collections.unmodifiableMap(regDerivations); 
168 kkz      1.1.2.9          }
169 kkz      1.1.2.9          /** Returns an unmodifiable <code>Map</code> of live derived 
170 kkz      1.1.2.9              pointers in <code>StackOffsetLoc</code>s to the 
171 kkz      1.1.2.9              derivation information in the form of <code>DLoc</code>s 
172 kkz      1.1.2.9              for that GC point */
173 kkz      1.1.2.9          public Map stackDerivations() { 
174 kkz      1.1.2.9              return Collections.unmodifiableMap(stackDerivations); 
175 kkz      1.1.2.9          }
176 kkz      1.1.2.9          /** Returns an unmodifiable <code>Set</code> of live, 
177 kkz      1.1.2.10             non-derived pointers at this GC point as
178 kkz      1.1.2.10             <code>WrappedStackOffsetLoc</code>s */
179 kkz      1.1.2.9          public Set liveStackOffsetLocs() { 
180 kkz      1.1.2.9              return Collections.unmodifiableSet(liveStackOffsetLocs); 
181 kkz      1.1.2.9          }
182 kkz      1.1.2.9          /** Returns an unmodifiable <code>Set</code> of live, 
183 kkz      1.1.2.10             non-derived pointers at this GC point as
184 kkz      1.1.2.10             <code>WrappedMachineRegLoc</code>s */
185 kkz      1.1.2.9          public Set liveMachineRegLocs() { 
186 kkz      1.1.2.9              return Collections.unmodifiableSet(liveMachineRegLocs); 
187 kkz      1.1.2.9          }
188 kkz      1.1.2.9          /** Returns an unmodifiable <code>Map</code> of callee-saved
189 kkz      1.1.2.9              <code>BackendDerivation.Register</code>s to the
190 kkz      1.1.2.9              <code>CommonLoc</code>s where its contents has been stored */
191 kkz      1.1.2.9          public Map calleeSaved() {
192 kkz      1.1.2.9              return Collections.unmodifiableMap(calleeSaved); 
193 kkz      1.1.2.9          }
194 kkz      1.1.2.9      }
195 kkz      1.1.2.9      /** <code>WrappedMachineRegLoc</code> is a wrapper object for
196 kkz      1.1.2.9          <code>MachineRegLoc</code>s that implement special
197 kkz      1.1.2.9          <code>equals</code> and <code>hashCode</code> methods.
198 kkz      1.1.2.9          Two <code>WrappedMachineRegLoc</code> objects are equal
199 kkz      1.1.2.9          if the underlying <code>MachineRegLoc</code>s represent
200 kkz      1.1.2.9          the same register.
201 kkz      1.1.2.9      */
202 kkz      1.1.2.9      public static class WrappedMachineRegLoc {
203 kkz      1.1.2.9          protected MachineRegLoc mrl;
204 kkz      1.1.2.9          /** Creates a <code>WrappedMachineRegLoc</code> object */
205 kkz      1.1.2.9          public WrappedMachineRegLoc(MachineRegLoc mrl) {
206 kkz      1.1.2.9              this.mrl = mrl;
207 kkz      1.1.2.9          }
208 kkz      1.1.2.9          /** Returns the abstract index of underlying 
209 kkz      1.1.2.9              <code>MachineRegLoc</code> in the register file.
210 kkz      1.1.2.9              The index returned is identical to what is
211 kkz      1.1.2.9              returned by the <code>regIndex</code> method of
212 kkz      1.1.2.9              the underlying <code>MachineRegLoc</code> object.
213 kkz      1.1.2.9          */
214 kkz      1.1.2.9          public int regIndex() {
215 kkz      1.1.2.9              return mrl.regIndex();
216 kkz      1.1.2.9          }
217 kkz      1.1.2.9          /** Compares two <code>WrappedMachineRegLoc</code> objects
218 kkz      1.1.2.9              for equality. Two <code>WrappedMachineRegLoc</code>
219 kkz      1.1.2.9              objects are equal if they represent the same register.
220 kkz      1.1.2.9          */
221 kkz      1.1.2.9          public boolean equals(Object obj) {
222 kkz      1.1.2.9              try {
223 kkz      1.1.2.9                  return (regIndex() == ((WrappedMachineRegLoc)obj).regIndex());
224 kkz      1.1.2.9              } catch (ClassCastException cce) {
225 kkz      1.1.2.9                  return false;
226 kkz      1.1.2.9              }
227 kkz      1.1.2.9          }
228 kkz      1.1.2.9          /** Returns the hash code value for the object. Two
229 kkz      1.1.2.9              <code>WrappedMachineRegLoc</code> return the same hash 
230 kkz      1.1.2.9              code if the underlying <code>MachineRegLoc</code>
231 kkz      1.1.2.9              objects represent the same register.
232 kkz      1.1.2.9          */
233 kkz      1.1.2.9          public int hashCode() {
234 kkz      1.1.2.9              // okay, i'm cheating quite a bit in this implementation
235 kkz      1.1.2.9              // but this s the simplest way I can think of to ensure 
236 kkz      1.1.2.9              // that two WrappedMachineRegLoc objects referring to the 
237 kkz      1.1.2.9              // same abstract register are equal
238 kkz      1.1.2.9              return ((new Integer(regIndex())).hashCode());
239 kkz      1.1.2.9          }
240 kkz      1.1.2.9      }
241 kkz      1.1.2.9      /** <code>WrappedStackOffsetLoc</code> is a wrapper object for
242 kkz      1.1.2.9          <code>StackOffsetLoc</code>s that implement special
243 kkz      1.1.2.9          <code>equals</code> and <code>hashCode</code> methods.
244 kkz      1.1.2.9          Two <code>StackOffsetLoc</code> objects are equal
245 kkz      1.1.2.9          if the underlying <code>StackOffsetLoc</code>s represent
246 kkz      1.1.2.9          the same stack offset.
247 kkz      1.1.2.9      */
248 kkz      1.1.2.9      public static class WrappedStackOffsetLoc {
249 kkz      1.1.2.9          protected StackOffsetLoc sol;
250 kkz      1.1.2.9          /** Creates a <code>WrappedStackOffsetLoc</code> object */
251 kkz      1.1.2.9          public WrappedStackOffsetLoc(StackOffsetLoc sol) {
252 kkz      1.1.2.9              this.sol = sol;
253 kkz      1.1.2.9          }
254 kkz      1.1.2.9          /** Returns the abstract stack offset of underlying 
255 kkz      1.1.2.9              <code>StackOffsetLoc</code>. The absolute location
256 kkz      1.1.2.9              in memory to which a stack offset refers is
257 kkz      1.1.2.9              context-dependent. For example, the stack offset of
258 kkz      1.1.2.9              an object in one method may have the same abstract
259 kkz      1.1.2.9              value as the stack offset of another object in a
260 kkz      1.1.2.9              different method, but they do not necessarily refer
261 kkz      1.1.2.9              to the same absolute location in the stack.
262 kkz      1.1.2.9              The stack offset returned is identical to what is
263 kkz      1.1.2.9              returned by the <code>stackOffset</code> method of
264 kkz      1.1.2.9              the underlying <code>StackOffsetLoc</code> object.
265 kkz      1.1.2.9          */
266 kkz      1.1.2.9          public int stackOffset() {
267 kkz      1.1.2.9              return sol.stackOffset();
268 kkz      1.1.2.9          }
269 kkz      1.1.2.9          /** Compares two <code>WrappedStackOffsetLoc</code> objects
270 kkz      1.1.2.9              for equality. Two <code>WrappedStackOffsetLoc</code>
271 kkz      1.1.2.9              objects are equal if they refer to the same abstract
272 kkz      1.1.2.9              stack offset.
273 kkz      1.1.2.9          */
274 kkz      1.1.2.9          public boolean equals(Object obj) {
275 kkz      1.1.2.9              try {
276 kkz      1.1.2.9                  return (stackOffset() == 
277 kkz      1.1.2.9                          ((WrappedStackOffsetLoc)obj).stackOffset());
278 kkz      1.1.2.9              } catch (ClassCastException cce) {
279 kkz      1.1.2.9                  return false;
280 kkz      1.1.2.9              }
281 kkz      1.1.2.9          }
282 kkz      1.1.2.9          /** Returns the hash code value for the object. Two
283 kkz      1.1.2.9              <code>WrappedStackOffsetLoc</code> return the same hash 
284 kkz      1.1.2.9              code if the underlying <code>StackOffsetLoc</code> refer
285 kkz      1.1.2.9              to the same abstract stack offset.
286 kkz      1.1.2.9          */
287 kkz      1.1.2.9          public int hashCode() {
288 kkz      1.1.2.9              // okay, i'm cheating quite a bit in this implementation
289 kkz      1.1.2.9              // but this s the simplest way I can think of to ensure 
290 kkz      1.1.2.9              // that two WrappedStackOffsetLoc objects referring to the 
291 kkz      1.1.2.9              // same abstract stack offset are equal
292 kkz      1.1.2.9              return ((new Integer(stackOffset())).hashCode());
293 kkz      1.1.2.9          }
294 kkz      1.1.2.1      }
295 kkz      1.1.2.5      /** 
296 kkz      1.1.2.5          Derivation information stored as <code>CommonLoc</code>s.
297 kkz      1.1.2.5       */
298 kkz      1.1.2.5      public static class DLoc {
299 kkz      1.1.2.5          /** Arrays of base pointer locations */
300 kkz      1.1.2.10         public final WrappedMachineRegLoc[] regLocs;
301 kkz      1.1.2.10         public final WrappedStackOffsetLoc[] stackLocs;
302 kkz      1.1.2.5          /** Arrays of booleans */
303 kkz      1.1.2.5          public final boolean[] regSigns;
304 kkz      1.1.2.5          public final boolean[] stackSigns;
305 kkz      1.1.2.5          /** Constructor. */
306 kkz      1.1.2.10         public DLoc(WrappedMachineRegLoc[] regLocs, 
307 kkz      1.1.2.10                     WrappedStackOffsetLoc[] stackLocs,
308 kkz      1.1.2.5                      boolean[] regSigns, boolean[] stackSigns) {
309 kkz      1.1.2.5              this.regLocs = regLocs;
310 kkz      1.1.2.5              this.stackLocs = stackLocs;
311 kkz      1.1.2.5              this.regSigns = regSigns;
312 kkz      1.1.2.5              this.stackSigns = stackSigns;
313 kkz      1.1.2.5          }
314 kkz      1.1.2.5      }
315 kkz      1.1.2.1  }
316 cananian 1.2