1 cananian 1.1.2.1  // Runtime.java, created Wed Sep  8 14:30:28 1999 by cananian
  2 cananian 1.1.2.1  // Copyright (C) 1999 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.Backend.Runtime1;
  5 cananian 1.1.2.1  
  6 cananian 1.1.2.1  import harpoon.Analysis.ClassHierarchy;
  7 cananian 1.1.2.28 import harpoon.Analysis.CallGraph;
  8 cananian 1.1.2.1  import harpoon.Backend.Generic.Frame;
  9 cananian 1.1.2.4  import harpoon.Backend.Maps.ClassDepthMap;
 10 cananian 1.1.2.1  import harpoon.Backend.Maps.NameMap;
 11 wbeebee  1.1.2.35 import harpoon.Backend.Runtime1.ObjectBuilder.RootOracle;
 12 cananian 1.1.2.1  import harpoon.ClassFile.HClass;
 13 cananian 1.1.2.11 import harpoon.ClassFile.HCode;
 14 cananian 1.1.2.11 import harpoon.ClassFile.HCodeFactory;
 15 cananian 1.3.2.2  import harpoon.ClassFile.HData;
 16 cananian 1.1.2.8  import harpoon.ClassFile.HMethod;
 17 cananian 1.1.2.16 import harpoon.ClassFile.Linker;
 18 cananian 1.3.2.5  import harpoon.IR.Tree.Stm;
 19 cananian 1.3.2.2  import harpoon.IR.Tree.Tree;
 20 cananian 1.3.2.5  import harpoon.IR.Tree.TreeFactory;
 21 cananian 1.1.2.43 import harpoon.Util.ParseUtil;
 22 cananian 1.1.2.11 import harpoon.Util.Util;
 23 cananian 1.1.2.11 
 24 cananian 1.1.2.11 import java.lang.reflect.Modifier;
 25 cananian 1.1.2.1  
 26 cananian 1.1.2.43 import java.util.ArrayList;
 27 cananian 1.1.2.1  import java.util.Arrays;
 28 cananian 1.1.2.12 import java.util.Collection;
 29 cananian 1.1.2.4  import java.util.HashSet;
 30 cananian 1.1.2.23 import java.util.Iterator;
 31 cananian 1.1.2.1  import java.util.List;
 32 cananian 1.1.2.4  import java.util.Set;
 33 cananian 1.1.2.1  /**
 34 cananian 1.1.2.2   * <code>Runtime1.Runtime</code> is a no-frills implementation of the runtime
 35 cananian 1.1.2.1   * abstract class.
 36 cananian 1.1.2.1   * 
 37 cananian 1.1.2.1   * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 38 cananian 1.11      * @version $Id: Runtime.java,v 1.11 2003/10/21 00:41:08 cananian Exp $
 39 cananian 1.1.2.1   */
 40 salcianu 1.9      public class Runtime extends harpoon.Backend.Generic.Runtime
 41 salcianu 1.9          implements java.io.Serializable {
 42 salcianu 1.9      
 43 wbeebee  1.1.2.35     // The package and subclasses should be able to access these fields. WSB
 44 wbeebee  1.1.2.35     final protected Frame frame; 
 45 wbeebee  1.1.2.35     final protected HMethod main;
 46 cananian 1.1.2.39     protected ClassHierarchy ch;
 47 cananian 1.1.2.39     protected CallGraph cg;
 48 cananian 1.1.2.39     final protected AllocationStrategy as;
 49 wbeebee  1.1.2.35     final protected ObjectBuilder ob;
 50 cananian 1.1.2.39     protected List staticInitializers;
 51 cananian 1.3.2.3      private harpoon.Backend.Runtime1.TreeBuilder treeBuilder;
 52 cananian 1.1.2.39     private NameMap nameMap;
 53 cananian 1.1.2.1      
 54 cananian 1.1.2.2      /** Creates a new <code>Runtime1.Runtime</code>. */
 55 cananian 1.1.2.7      public Runtime(Frame frame, AllocationStrategy as,
 56 cananian 1.1.2.39                    HMethod main, boolean prependUnderscore) {
 57 cananian 1.1.2.39         this(frame, as, main, prependUnderscore, null);
 58 wbeebee  1.1.2.35     }
 59 wbeebee  1.1.2.35 
 60 wbeebee  1.1.2.35     /** Creates a new <code>Runtime1.Runtime</code>. */
 61 wbeebee  1.1.2.35     public Runtime(Frame frame, AllocationStrategy as,
 62 cananian 1.1.2.39                    HMethod main,
 63 wbeebee  1.1.2.35                    boolean prependUnderscore, RootOracle rootOracle) {
 64 cananian 1.1.2.4          this.frame = frame;
 65 cananian 1.1.2.8          this.main = main;
 66 cananian 1.1.2.39         this.as = as;
 67 cananian 1.1.2.39         this.nameMap =
 68 cananian 1.1.2.39             new harpoon.Backend.Maps.DefaultNameMap(prependUnderscore);
 69 cananian 1.3.2.5          this.ob = initObjectBuilder(rootOracle);
 70 cananian 1.1.2.39         this.treeBuilder = initTreeBuilder();
 71 cananian 1.1.2.4      }
 72 cananian 1.3.2.5      protected ObjectBuilder initObjectBuilder(RootOracle ro) {
 73 cananian 1.3.2.5          if (ro==null)
 74 cananian 1.3.2.5              return new harpoon.Backend.Runtime1.ObjectBuilder(this);
 75 cananian 1.3.2.5          return new harpoon.Backend.Runtime1.ObjectBuilder(this, ro);
 76 cananian 1.3.2.5      }
 77 cananian 1.3.2.3      public harpoon.Backend.Runtime1.TreeBuilder
 78 cananian 1.3.2.3          getTreeBuilder() { return treeBuilder; }
 79 cananian 1.1.2.39     public NameMap getNameMap() { return nameMap; }
 80 cananian 1.1.2.39     public String resourcePath(String basename) {
 81 cananian 1.6              if (Boolean.getBoolean("harpoon.runtime1.sunjdk")) {
 82 cananian 1.5                  basename="sunjdk."+basename;
 83 cananian 1.6                  configurationSet.add("check_with_sunjdk_needed");
 84 cananian 1.10             } else if (Boolean.getBoolean("harpoon.runtime1.minilib")) {
 85 cananian 1.10                 basename="minilib."+basename;
 86 cananian 1.10                 // minilib uses the classpath native library support.
 87 cananian 1.10                 configurationSet.add("check_with_classpath_needed");
 88 cananian 1.6              } else
 89 cananian 1.6                  configurationSet.add("check_with_classpath_needed");
 90 cananian 1.1.2.39         return "harpoon/Backend/Runtime1/"+basename;
 91 cananian 1.1.2.39     }
 92 cananian 1.1.2.39 
 93 cananian 1.1.2.39     public void setCallGraph(CallGraph cg) { this.cg = cg; }
 94 cananian 1.1.2.39     // this method must be called before (certain methods in) the tree
 95 cananian 1.1.2.39     // builder are used.
 96 cananian 1.1.2.39     public void setClassHierarchy(ClassHierarchy ch) {
 97 cananian 1.1.2.39         this.ch = ch;
 98 cananian 1.1.2.41         // class and field information may have changed; reset caches.
 99 cananian 1.1.2.41         treeBuilder = initTreeBuilder();
100 cananian 1.1.2.41         // set the treebuilder's class hierarchy.
101 cananian 1.3.2.3          treeBuilder.setClassHierarchy(ch);
102 cananian 1.1.2.39     }
103 cananian 1.3.2.3      protected  harpoon.Backend.Runtime1.TreeBuilder initTreeBuilder() {
104 cananian 1.1.2.38         int align = Integer.parseInt
105 cananian 1.1.2.38             (System.getProperty("harpoon.runtime1.pointer.alignment","0"));
106 cananian 1.1.2.42         // config-checking --- this property shouldn't change!
107 cananian 1.1.2.42         if (align!=0)
108 cananian 1.1.2.42             configurationSet.add("check_with_masked_pointers_needed");
109 cananian 1.3.2.4          // more config-checking -- using this tree builder means no
110 cananian 1.3.2.6          // claz compression support and no hashlock compression support.
111 cananian 1.3.2.4          configurationSet.add("check_with_claz_shrink_not_needed");
112 cananian 1.3.2.6          configurationSet.add("check_with_hashlock_shrink_not_needed");
113 cananian 1.1.2.39         return new harpoon.Backend.Runtime1.TreeBuilder
114 cananian 1.1.2.39             (this, frame.getLinker(), as, frame.pointersAreLong(), align);
115 cananian 1.1.2.11     }
116 cananian 1.1.2.11 
117 cananian 1.1.2.11     public HCodeFactory nativeTreeCodeFactory(final HCodeFactory hcf) {
118 cananian 1.1.2.23         final HMethod HMobjAclone =
119 cananian 1.1.2.23             frame.getLinker().forDescriptor("[Ljava/lang/Object;")
120 cananian 1.1.2.23             .getMethod("clone", new HClass[0]);
121 cananian 1.3.2.1          assert hcf.getCodeName().endsWith("tree");
122 cananian 1.1.2.11         return new HCodeFactory() {
123 cananian 1.1.2.11             public String getCodeName() { return hcf.getCodeName(); }
124 cananian 1.1.2.11             public void clear(HMethod m) { hcf.clear(m); }
125 cananian 1.1.2.11             public HCode convert(HMethod m) {
126 cananian 1.1.2.11                 HCode c = hcf.convert(m);
127 cananian 1.1.2.11                 // substitute stub for native methods.
128 cananian 1.1.2.30                 if (c==null && Modifier.isNative(m.getModifiers()))
129 cananian 1.1.2.30                     c = new StubCode(m, frame);
130 cananian 1.1.2.11                 return c;
131 cananian 1.1.2.11             }
132 cananian 1.1.2.11         };
133 cananian 1.1.2.23     }
134 cananian 1.1.2.12 
135 cananian 1.1.2.39     public Collection runtimeCallableMethods() {
136 cananian 1.8              final Linker linker = frame.getLinker();
137 cananian 1.8              String methodResourceName = resourcePath("method-root.properties");
138 cananian 1.8              String classResourceName = resourcePath("class-root.properties");
139 cananian 1.8      
140 cananian 1.8              // XXX this is a little crufty, as backwards compatibility
141 cananian 1.8              // made this a weird little interface.
142 cananian 1.8      
143 cananian 1.1.2.43         // read in root methods and classes from properties files.
144 cananian 1.1.2.43         try {
145 cananian 1.1.2.43             final List result = new ArrayList();
146 cananian 1.1.2.43             // read in method roots
147 cananian 1.1.2.43             ParseUtil.readResource
148 cananian 1.1.2.43                 (methodResourceName,
149 cananian 1.1.2.43                  new ParseUtil.StringParser() {
150 cananian 1.1.2.43                          public void parseString(String s)
151 cananian 1.1.2.43                              throws ParseUtil.BadLineException {
152 cananian 1.1.2.43                              result.add(ParseUtil.parseMethod(linker, s));
153 cananian 1.1.2.43                          }
154 cananian 1.1.2.43                      });
155 cananian 1.1.2.43             // read in class roots.
156 cananian 1.1.2.43             ParseUtil.readResource
157 cananian 1.1.2.43                 (classResourceName,
158 cananian 1.1.2.43                  new ParseUtil.StringParser() {
159 cananian 1.1.2.43                          public void parseString(String s)
160 cananian 1.1.2.43                              throws ParseUtil.BadLineException {
161 cananian 1.1.2.43                              result.add(linker.forDescriptor(s));
162 cananian 1.1.2.43                          }
163 cananian 1.1.2.43                      });
164 cananian 1.1.2.43             // done!
165 cananian 1.1.2.43             return result;
166 cananian 1.1.2.43         } catch (java.io.IOException ioex) {
167 cananian 1.1.2.43             // this includes BadLineExceptions.  We could just skip the
168 cananian 1.1.2.43             // rest of the file, but the importance of these sets
169 cananian 1.1.2.43             // justifies halting compilation with a RuntimeException.
170 cananian 1.1.2.43             throw new RuntimeException("Can't read roots: "+ioex);
171 cananian 1.1.2.43         }
172 cananian 1.1.2.4      }
173 cananian 1.1.2.4  
174 cananian 1.1.2.39     private synchronized void freeze() {
175 cananian 1.1.2.39         if (frozen) return; else frozen = true;
176 cananian 1.1.2.39 
177 cananian 1.1.2.39         // finalize static initializers.
178 cananian 1.1.2.39         if (Boolean.getBoolean("harpoon.runtime1.order-initializers"))
179 cananian 1.1.2.39             this.staticInitializers =
180 cananian 1.1.2.39                 new harpoon.Backend.Analysis.InitializerOrdering(ch, cg)
181 cananian 1.1.2.39                 .sorted;
182 cananian 1.1.2.39         else { // when using InitializerTransform, can order randomly:
183 cananian 1.1.2.39             this.staticInitializers = new java.util.ArrayList();
184 cananian 1.1.2.39             for (Iterator it=ch.classes().iterator(); it.hasNext(); ) {
185 cananian 1.1.2.39                 HMethod hm = ((HClass)it.next()).getClassInitializer();
186 cananian 1.1.2.39                 if (hm!=null) staticInitializers.add(hm);
187 cananian 1.1.2.39             }
188 cananian 1.1.2.39         }
189 cananian 1.1.2.39     }
190 cananian 1.1.2.39     private boolean frozen=false;
191 cananian 1.1.2.39 
192 cananian 1.3.2.2      public List<HData> classData(HClass hc) {
193 cananian 1.1.2.39         freeze();
194 cananian 1.1.2.39 
195 cananian 1.1.2.4          // i don't particularly like this solution to generating
196 cananian 1.1.2.4          // the needed string constants, but it works.
197 cananian 1.3.2.3          treeBuilder.stringSet.removeAll(stringsSeen);
198 cananian 1.3.2.3          stringsSeen.addAll(treeBuilder.stringSet);
199 cananian 1.3.2.3          Set<String> newStrings = new HashSet<String>(treeBuilder.stringSet);
200 cananian 1.3.2.3          treeBuilder.stringSet.clear();
201 cananian 1.1.2.1  
202 cananian 1.3.2.3          List<HData> r = new java.util.ArrayList<HData>(20);
203 cananian 1.3.2.3          r.addAll(Arrays.asList(new HData[] {
204 cananian 1.3.2.5              new DataClaz(frame, hc, ch, getExtraClazInfo()),
205 cananian 1.1.2.42             new DataConfigChecker(frame, hc),
206 cananian 1.1.2.4              new DataInterfaceList(frame, hc, ch),
207 cananian 1.1.2.4              new DataStaticFields(frame, hc),
208 cananian 1.1.2.4              new DataStrings(frame, hc, newStrings),
209 cananian 1.1.2.7              new DataInitializers(frame, hc, staticInitializers),
210 cananian 1.1.2.8              new DataJavaMain(frame, hc, main),
211 cananian 1.1.2.9              new DataReflection1(frame, hc, ch),
212 cananian 1.11                 new DataReflection2(frame, hc, ch),
213 cananian 1.1.2.32             new DataReflectionMemberList(frame, hc, ch),
214 cananian 1.3.2.3          }));
215 cananian 1.3.2.3          if (frame.getGCInfo() != null)
216 cananian 1.1.2.32             r.add(new DataGC(frame, hc));
217 cananian 1.1.2.32         return r;
218 cananian 1.1.2.1      }
219 cananian 1.3.2.2      final Set<String> stringsSeen = new HashSet<String>();
220 cananian 1.3.2.5  
221 cananian 1.3.2.5      /** provides a means for a subclass to add extra fields to
222 cananian 1.3.2.5       * DataClaz.  A little bit cleaner than trying to subclass
223 cananian 1.3.2.5       * DataClaz and hack TreeBuilder to make this work. */
224 cananian 1.3.2.5      protected static class ExtraClazInfo {
225 cananian 1.3.2.5          /** Return the number of bytes of fields you're planning on sticking
226 cananian 1.3.2.5           *  into the claz structure. */
227 cananian 1.3.2.5          public int fields_size() { return 0; }
228 cananian 1.3.2.5          /** Here's your chance to insert your stuff. */
229 cananian 1.3.2.5          public Stm emit(TreeFactory tf, Frame f, HClass hc, ClassHierarchy ch){
230 cananian 1.3.2.5              return null;
231 cananian 1.1.2.32         }
232 cananian 1.1.2.1      }
233 cananian 1.3.2.5      /** A means for a subclass to set this. */
234 cananian 1.3.2.5      protected ExtraClazInfo getExtraClazInfo() { return new ExtraClazInfo(); }
235 cananian 1.2      }