1 cananian 1.1.2.35 // CloningVisitor.java, created Mon Feb  7 17:04:30 2000 by bdemsky
   2 cananian 1.1.2.35 // Copyright (C) 2000 Brian Demsky <bdemsky@mit.edu>
   3 bdemsky  1.1.2.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
   4 bdemsky  1.1.2.1  package harpoon.Analysis.EventDriven;
   5 bdemsky  1.1.2.1  
   6 bdemsky  1.1.2.1  
   7 bdemsky  1.1.2.1  import harpoon.Analysis.ContBuilder.ContBuilder;
   8 bdemsky  1.1.2.1  import harpoon.Analysis.EnvBuilder.EnvBuilder;
   9 bdemsky  1.1.2.1  import harpoon.Analysis.Quads.QuadLiveness;
  10 bdemsky  1.1.2.1  import harpoon.Analysis.ClassHierarchy;
  11 bdemsky  1.1.2.1  import harpoon.Analysis.Maps.TypeMap;
  12 bdemsky  1.1.2.10 import harpoon.Analysis.AllCallers;
  13 bdemsky  1.1.2.1  import harpoon.ClassFile.CachingCodeFactory;
  14 bdemsky  1.1.2.1  import harpoon.ClassFile.HClass;
  15 bdemsky  1.1.2.1  import harpoon.ClassFile.HClassMutator;
  16 bdemsky  1.1.2.1  import harpoon.ClassFile.HMethod;
  17 bdemsky  1.1.2.1  import harpoon.ClassFile.HMethodMutator;
  18 bdemsky  1.1.2.1  import harpoon.ClassFile.HCode;
  19 bdemsky  1.1.2.1  import harpoon.ClassFile.HConstructor;
  20 bdemsky  1.1.2.1  import harpoon.ClassFile.HField;
  21 bdemsky  1.1.2.1  import harpoon.ClassFile.Loader;
  22 bdemsky  1.1.2.1  import harpoon.ClassFile.Linker;
  23 bdemsky  1.1.2.1  import harpoon.ClassFile.UniqueName;
  24 bdemsky  1.1.2.1  
  25 bdemsky  1.1.2.1  import harpoon.IR.Quads.CALL;
  26 bdemsky  1.1.2.1  import harpoon.IR.Quads.CJMP;
  27 bdemsky  1.1.2.1  import harpoon.IR.Quads.CONST;
  28 bdemsky  1.1.2.1  import harpoon.IR.Quads.Code;
  29 bdemsky  1.1.2.1  import harpoon.IR.Quads.Edge;
  30 bdemsky  1.1.2.1  import harpoon.IR.Quads.FOOTER;
  31 bdemsky  1.1.2.1  import harpoon.IR.Quads.GET;
  32 bdemsky  1.1.2.6  import harpoon.IR.Quads.INSTANCEOF;
  33 bdemsky  1.1.2.10 import harpoon.IR.Quads.NOP;
  34 bdemsky  1.1.2.1  import harpoon.IR.Quads.SET;
  35 bdemsky  1.1.2.1  import harpoon.IR.Quads.HEADER;
  36 bdemsky  1.1.2.1  import harpoon.IR.Quads.METHOD;
  37 bdemsky  1.1.2.1  import harpoon.IR.Quads.NEW;
  38 bdemsky  1.1.2.24 import harpoon.IR.Quads.ANEW;
  39 bdemsky  1.1.2.1  import harpoon.IR.Quads.OPER;
  40 bdemsky  1.1.2.1  import harpoon.IR.Quads.Qop;
  41 bdemsky  1.1.2.1  import harpoon.IR.Quads.PHI;
  42 bdemsky  1.1.2.1  import harpoon.IR.Quads.Quad;
  43 bdemsky  1.1.2.1  import harpoon.IR.Quads.QuadFactory;
  44 bdemsky  1.1.2.2  import harpoon.IR.Quads.QuadSSI;
  45 bdemsky  1.1.2.1  import harpoon.IR.Quads.RETURN;
  46 bdemsky  1.1.2.1  import harpoon.IR.Quads.THROW;
  47 bdemsky  1.1.2.1  import harpoon.IR.Quads.TYPECAST;
  48 bdemsky  1.1.2.1  import harpoon.IR.Quads.QuadVisitor;
  49 bdemsky  1.1.2.1  import harpoon.Temp.Temp;
  50 bdemsky  1.1.2.1  import harpoon.Temp.TempFactory;
  51 bdemsky  1.1.2.1  import harpoon.Temp.CloningTempMap;
  52 bdemsky  1.1.2.2  import harpoon.Temp.TempMap;
  53 bdemsky  1.1.2.1  import harpoon.Util.Util;
  54 cananian 1.7      import net.cscott.jutil.WorkSet;
  55 bdemsky  1.1.2.1  
  56 bdemsky  1.1.2.1  import java.util.HashMap;
  57 bdemsky  1.1.2.1  import java.util.Iterator;
  58 bdemsky  1.1.2.1  import java.util.Map;
  59 bdemsky  1.1.2.1  import java.util.Set;
  60 bdemsky  1.1.2.5  import java.util.Arrays;
  61 bdemsky  1.1.2.24 import java.util.Vector;
  62 bdemsky  1.1.2.5  import java.util.Collections;
  63 bdemsky  1.1.2.1  import java.lang.reflect.Modifier;
  64 bdemsky  1.1.2.21 
  65 bdemsky  1.1.2.21 import harpoon.Analysis.AllocationInformationMap;
  66 bdemsky  1.1.2.21 import harpoon.Analysis.Maps.AllocationInformation;
  67 bdemsky  1.1.2.21 
  68 bdemsky  1.1.2.1  /**
  69 bdemsky  1.1.2.1   * <code>CloningVisitor</code>
  70 bdemsky  1.1.2.1   * 
  71 cananian 1.1.2.35  * @author  Brian Demsky <bdemsky@mit.edu>
  72 cananian 1.8       * @version $Id: CloningVisitor.java,v 1.8 2004/02/08 03:19:30 cananian Exp $
  73 bdemsky  1.1.2.1   */
  74 bdemsky  1.1.2.1  public class CloningVisitor extends QuadVisitor {
  75 bdemsky  1.1.2.1      boolean isCont, followchildren, methodstatus;
  76 bdemsky  1.1.2.1      CachingCodeFactory ucf;
  77 bdemsky  1.1.2.1      ClassHierarchy ch;
  78 bdemsky  1.1.2.1      CloningTempMap ctmap;
  79 bdemsky  1.1.2.5      harpoon.IR.Quads.Code hcode;
  80 bdemsky  1.1.2.1      HashMap quadmap;
  81 bdemsky  1.1.2.1      HCode hc;
  82 bdemsky  1.1.2.1      HMethod mroot;
  83 bdemsky  1.1.2.1      Linker linker;
  84 bdemsky  1.1.2.1      Map cont_map, old2new, env_map;     
  85 bdemsky  1.1.2.1      Set blockingcalls, cont_todo, async_todo, phiset;
  86 bdemsky  1.1.2.1      Set addedCall, other, done_other;
  87 bdemsky  1.1.2.1      Temp tthis;
  88 bdemsky  1.1.2.10     BMethod bm;
  89 bdemsky  1.1.2.1      QuadLiveness liveness;
  90 bdemsky  1.1.2.1      WorkSet linkFooters;
  91 bdemsky  1.1.2.2      TypeMap typemap;
  92 bdemsky  1.1.2.5      QuadFactory qf;
  93 bdemsky  1.1.2.5      boolean stillokay;
  94 bdemsky  1.1.2.10     boolean optimistic;
  95 bdemsky  1.1.2.14     boolean recycle;
  96 bdemsky  1.1.2.10     Set blocking;
  97 bdemsky  1.1.2.14     CALL origCall;
  98 bdemsky  1.1.2.16     Set cclasses;
  99 bdemsky  1.1.2.21     AllocationInformation oldai;
 100 bdemsky  1.1.2.21     AllocationInformationMap newai;
 101 bdemsky  1.1.2.14 
 102 bdemsky  1.1.2.1      public CloningVisitor(Set blockingcalls, Set cont_todo,
 103 bdemsky  1.1.2.1                            Map cont_map, Map env_map, 
 104 bdemsky  1.1.2.1                            QuadLiveness liveness, Set async_todo,
 105 bdemsky  1.1.2.1                            Map old2new, 
 106 bdemsky  1.1.2.1                            HCode hc, CachingCodeFactory ucf,
 107 bdemsky  1.1.2.10                           AllCallers.MethodSet bm, HMethod mroot, 
 108 bdemsky  1.1.2.1                            Linker linker, ClassHierarchy ch,
 109 bdemsky  1.1.2.1                            Set other, Set done_other, 
 110 bdemsky  1.1.2.10                           boolean methodstatus, TypeMap typemap,
 111 bdemsky  1.1.2.16                           boolean optimistic, boolean recycle, Set cclasses) {
 112 bdemsky  1.1.2.1          this.liveness=liveness;
 113 bdemsky  1.1.2.1          this.blockingcalls=blockingcalls;
 114 bdemsky  1.1.2.1          this.cont_todo=cont_todo;
 115 bdemsky  1.1.2.1          this.cont_map=cont_map;
 116 bdemsky  1.1.2.1          this.async_todo=async_todo;
 117 bdemsky  1.1.2.1          this.old2new=old2new;
 118 bdemsky  1.1.2.1          this.env_map=env_map;
 119 bdemsky  1.1.2.1          this.ucf=ucf;
 120 bdemsky  1.1.2.1          this.hc=hc;
 121 bdemsky  1.1.2.10         this.bm=(BMethod)bm;
 122 bdemsky  1.1.2.1          this.mroot=mroot;
 123 bdemsky  1.1.2.1          this.linker=linker;
 124 bdemsky  1.1.2.1          this.ch=ch;
 125 bdemsky  1.1.2.1          this.other=other;
 126 bdemsky  1.1.2.1          this.done_other=done_other;
 127 bdemsky  1.1.2.1          this.methodstatus=methodstatus;
 128 bdemsky  1.1.2.2          this.typemap=typemap;
 129 bdemsky  1.1.2.10         this.optimistic=optimistic;
 130 bdemsky  1.1.2.14         this.recycle=recycle;
 131 bdemsky  1.1.2.16         this.cclasses=cclasses;
 132 bdemsky  1.1.2.21         this.oldai=((QuadSSI)hc).getAllocationInformation();
 133 bdemsky  1.1.2.1      }
 134 bdemsky  1.1.2.1  
 135 bdemsky  1.1.2.14     public void reset(HMethod nhm, TempFactory otf, boolean isCont, CALL origCall) {
 136 bdemsky  1.1.2.1          followchildren=true;
 137 bdemsky  1.1.2.5          hcode=new ContCodeSSI(nhm);
 138 bdemsky  1.1.2.21         if (oldai!=null) {
 139 bdemsky  1.1.2.21             newai=new AllocationInformationMap();
 140 bdemsky  1.1.2.21             ((QuadSSI)hcode).setAllocationInformation(newai);
 141 bdemsky  1.1.2.21         }
 142 bdemsky  1.1.2.17         cclasses.add(nhm.getDeclaringClass());
 143 bdemsky  1.1.2.5          qf=((ContCodeSSI)hcode).getFactory();
 144 bdemsky  1.1.2.5          stillokay=methodstatus;
 145 bdemsky  1.1.2.5          ctmap=new CloningTempMap(otf,qf.tempFactory());
 146 bdemsky  1.1.2.1          quadmap=new HashMap();
 147 bdemsky  1.1.2.1          this.isCont=isCont;
 148 bdemsky  1.1.2.10         linkFooters=new WorkSet();
 149 bdemsky  1.1.2.1          if (isCont)
 150 bdemsky  1.1.2.5              tthis=new Temp(qf.tempFactory());
 151 bdemsky  1.1.2.1          else
 152 bdemsky  1.1.2.1              tthis=null;
 153 bdemsky  1.1.2.1          phiset=new WorkSet();
 154 bdemsky  1.1.2.1          addedCall=new WorkSet();
 155 bdemsky  1.1.2.10         if (optimistic)
 156 bdemsky  1.1.2.10             blocking=new WorkSet();
 157 bdemsky  1.1.2.10         else
 158 bdemsky  1.1.2.10             blocking=null;
 159 bdemsky  1.1.2.14         this.origCall=origCall;
 160 bdemsky  1.1.2.1      }
 161 bdemsky  1.1.2.1      
 162 bdemsky  1.1.2.1      public HCode getCode() {
 163 bdemsky  1.1.2.1          return hcode;
 164 bdemsky  1.1.2.1      }
 165 bdemsky  1.1.2.1  
 166 bdemsky  1.1.2.1      public boolean follow() {
 167 bdemsky  1.1.2.1          return followchildren;
 168 bdemsky  1.1.2.1      }
 169 bdemsky  1.1.2.1      
 170 bdemsky  1.1.2.5      HClass getEnv(CALL q) {
 171 bdemsky  1.1.2.1          if (env_map.containsKey(q))
 172 bdemsky  1.1.2.1              return (HClass) env_map.get(q);
 173 bdemsky  1.1.2.1          HClass nhclass=(new EnvBuilder(ucf, hc, 
 174 bdemsky  1.1.2.5                                         q, getEnvTemps(q),linker,
 175 bdemsky  1.1.2.14                                        typemap,recycle)).makeEnv();
 176 bdemsky  1.1.2.17         //force outputting of this class
 177 bdemsky  1.1.2.17         cclasses.add(nhclass);
 178 bdemsky  1.1.2.1          env_map.put(q, nhclass);
 179 bdemsky  1.1.2.1          return nhclass;
 180 bdemsky  1.1.2.1      }
 181 bdemsky  1.1.2.1  
 182 bdemsky  1.1.2.1      
 183 bdemsky  1.1.2.1      //Adds edges between quads and environment loading code
 184 bdemsky  1.1.2.1      public void addEdges(Quad q, int resumeexception, Set dontfollow) {
 185 bdemsky  1.1.2.6          HEADER header;
 186 bdemsky  1.1.2.1          if (resumeexception!=-1) {
 187 bdemsky  1.1.2.1              //Doing addedges for CALL continuation
 188 bdemsky  1.1.2.1              //Need to build headers here....[continuation]
 189 bdemsky  1.1.2.1              //Need to load environment object and result codes
 190 bdemsky  1.1.2.1              
 191 bdemsky  1.1.2.1              addEdges(q.next(resumeexception),dontfollow);
 192 bdemsky  1.1.2.6              header=buildEnvironmentExtracter((CALL)q, resumeexception);
 193 bdemsky  1.1.2.1              
 194 bdemsky  1.1.2.1              fixphis();
 195 bdemsky  1.1.2.5              ((ContCodeSSI)hcode).quadSet(header);
 196 bdemsky  1.1.2.5  
 197 bdemsky  1.1.2.1          } else {
 198 bdemsky  1.1.2.1              //Doing addEdges for HEADER
 199 bdemsky  1.1.2.1              Quad.addEdge((Quad)quadmap.get(q),1,
 200 bdemsky  1.1.2.1                           (Quad)quadmap.get(q.next(1)),q.nextEdge(1).which_pred());
 201 bdemsky  1.1.2.1              addEdges(q.next(1),dontfollow);
 202 bdemsky  1.1.2.6  
 203 bdemsky  1.1.2.6  
 204 bdemsky  1.1.2.6              header=(HEADER) quadmap.get(q);
 205 bdemsky  1.1.2.1              fixphis();
 206 bdemsky  1.1.2.5             
 207 bdemsky  1.1.2.6              ((ContCodeSSI)hcode).quadSet(header);
 208 bdemsky  1.1.2.5             
 209 bdemsky  1.1.2.1          }
 210 bdemsky  1.1.2.6          FOOTER footer=new FOOTER(qf, q, linkFooters.size()+1);
 211 bdemsky  1.1.2.6          Quad.addEdge(header,0,footer,0);
 212 bdemsky  1.1.2.6          Iterator fiterator=linkFooters.iterator();
 213 bdemsky  1.1.2.6          int count=1;
 214 bdemsky  1.1.2.6          while(fiterator.hasNext())
 215 bdemsky  1.1.2.6              Quad.addEdge((Quad)fiterator.next(), 0, footer, count++);
 216 bdemsky  1.1.2.1      }
 217 bdemsky  1.1.2.1  
 218 bdemsky  1.1.2.1      public void visit(RETURN q) {
 219 bdemsky  1.1.2.1          if (methodstatus) {
 220 bdemsky  1.1.2.1              //We are just doing swaps on this method, so just clone
 221 bdemsky  1.1.2.5              Object nq=q.clone(qf, ctmap);
 222 bdemsky  1.1.2.1              quadmap.put(q, nq);
 223 bdemsky  1.1.2.1              linkFooters.add(nq);
 224 bdemsky  1.1.2.1          } else if (isCont)
 225 bdemsky  1.1.2.1              buildReturnContinuation(q, q.retval(), true);
 226 bdemsky  1.1.2.10         else 
 227 bdemsky  1.1.2.1              buildDoneContinuation(q, q.retval(),true);
 228 bdemsky  1.1.2.1          followchildren=false;
 229 bdemsky  1.1.2.1      }
 230 bdemsky  1.1.2.1          
 231 bdemsky  1.1.2.1      public void visit(THROW q) {
 232 bdemsky  1.1.2.5          TempFactory tf=qf.tempFactory();
 233 bdemsky  1.1.2.1          if (methodstatus) {
 234 bdemsky  1.1.2.1              //We are just doing swaps on this method, so just clone
 235 bdemsky  1.1.2.5              Object nq=q.clone(qf, ctmap);
 236 bdemsky  1.1.2.1              quadmap.put(q, nq);
 237 bdemsky  1.1.2.1              linkFooters.add(nq);
 238 bdemsky  1.1.2.1          } else if (isCont)
 239 bdemsky  1.1.2.1              buildReturnContinuation(q, q.throwable(), false);
 240 bdemsky  1.1.2.10         else if (optimistic) {
 241 bdemsky  1.1.2.10             Object nq=q.clone(qf,ctmap);
 242 bdemsky  1.1.2.10             quadmap.put(q,nq);
 243 bdemsky  1.1.2.10             linkFooters.add(nq);
 244 bdemsky  1.1.2.10         } else
 245 bdemsky  1.1.2.1              buildDoneContinuation(q, q.throwable(),false);
 246 bdemsky  1.1.2.1          followchildren=false;
 247 bdemsky  1.1.2.1      }
 248 bdemsky  1.1.2.1      
 249 bdemsky  1.1.2.1      public void visit(Quad q) {
 250 bdemsky  1.1.2.1          followchildren=true;
 251 bdemsky  1.1.2.5          quadmap.put(q, q.clone(qf, ctmap));
 252 bdemsky  1.1.2.1      }
 253 bdemsky  1.1.2.21 
 254 bdemsky  1.1.2.21     public void visit(NEW q) {
 255 bdemsky  1.1.2.21         //DONE AIMAP[if !methodstatus then change stack-->Thread Heap] 
 256 bdemsky  1.1.2.21         followchildren=true;
 257 bdemsky  1.1.2.21         Quad qc=(Quad)q.clone(qf,ctmap);
 258 bdemsky  1.1.2.21         quadmap.put(q, qc);
 259 bdemsky  1.1.2.21         if (newai!=null)
 260 bdemsky  1.1.2.21             if (methodstatus) {
 261 bdemsky  1.1.2.21                 newai.transfer(qc,q,ctmap, oldai);
 262 bdemsky  1.1.2.21             } else {
 263 bdemsky  1.1.2.21                 AllocationInformation.AllocationProperties aiprop=oldai.query(q);
 264 bdemsky  1.1.2.21                 newai.associate(qc,new AllocationInformationMap.AllocationPropertiesImpl(aiprop.hasInteriorPointers(),
 265 bdemsky  1.1.2.21                                                                                          false,
 266 bdemsky  1.1.2.21                                                                                          aiprop.canBeThreadAllocated()||aiprop.canBeStackAllocated(),
 267 cananian 1.1.2.29                                                                                          aiprop.makeHeap(),
 268 salcianu 1.1.2.34                                                                                          false, // DEFAULT
 269 kkz      1.1.2.31                                                                                          (aiprop.allocationHeap()!=null)?ctmap.tempMap(aiprop.allocationHeap()) : null,
 270 kkz      1.6                                                                                               ((NEW)qc).hclass(),
 271 kkz      1.6                                                                                               false));
 272 bdemsky  1.1.2.21             }
 273 bdemsky  1.1.2.21     }
 274 bdemsky  1.1.2.24 
 275 bdemsky  1.1.2.24     public void visit(ANEW q) {
 276 bdemsky  1.1.2.24         //DONE AIMAP[if !methodstatus then change stack-->Thread Heap] 
 277 bdemsky  1.1.2.24         followchildren=true;
 278 bdemsky  1.1.2.24         Quad qc=(Quad)q.clone(qf,ctmap);
 279 bdemsky  1.1.2.24         quadmap.put(q, qc);
 280 bdemsky  1.1.2.24         if (newai!=null)
 281 bdemsky  1.1.2.24             if (methodstatus) {
 282 bdemsky  1.1.2.24                 newai.transfer(qc,q,ctmap, oldai);
 283 bdemsky  1.1.2.24             } else {
 284 bdemsky  1.1.2.24                 AllocationInformation.AllocationProperties aiprop=oldai.query(q);
 285 bdemsky  1.1.2.24                 newai.associate(qc,new AllocationInformationMap.AllocationPropertiesImpl(aiprop.hasInteriorPointers(),
 286 bdemsky  1.1.2.24                                                                                          false,
 287 bdemsky  1.1.2.24                                                                                          aiprop.canBeThreadAllocated()||aiprop.canBeStackAllocated(),
 288 cananian 1.1.2.29                                                                                          aiprop.makeHeap(),
 289 salcianu 1.1.2.34                                                                                          false, // DEFAULT
 290 kkz      1.1.2.31                                                                                          (aiprop.allocationHeap()!=null)?ctmap.tempMap(aiprop.allocationHeap()) : null,
 291 kkz      1.6                                                                                               ((ANEW)qc).hclass(),
 292 kkz      1.6                                                                                               false));
 293 bdemsky  1.1.2.24             }
 294 bdemsky  1.1.2.24     }
 295 bdemsky  1.1.2.1      
 296 bdemsky  1.1.2.1      public void visit(PHI q) {
 297 bdemsky  1.1.2.1          followchildren=true;
 298 bdemsky  1.1.2.5          Object qc=q.clone(qf, ctmap);
 299 bdemsky  1.1.2.1          quadmap.put(q, qc);
 300 bdemsky  1.1.2.1          phiset.add(qc);
 301 bdemsky  1.1.2.1      }
 302 bdemsky  1.1.2.1      
 303 bdemsky  1.1.2.1      public void visit(CALL q) {
 304 bdemsky  1.1.2.8          checkdoneothers(q);
 305 bdemsky  1.1.2.1          if ((methodstatus==false)&&
 306 bdemsky  1.1.2.1              (!q.method().getName().equals("<init>"))&&
 307 bdemsky  1.1.2.1              isBlocking(q)) {
 308 bdemsky  1.1.2.1              if (!cont_map.containsKey(q)) {
 309 bdemsky  1.1.2.1                  //Add this CALL to list of calls to build continuations for
 310 bdemsky  1.1.2.1                  cont_todo.add(q);
 311 bdemsky  1.1.2.1                  //Build Class for the continuation
 312 bdemsky  1.1.2.1                  HClass hclass=AsyncCode.createContinuation(hc.getMethod(),  q,
 313 bdemsky  1.1.2.13                                                  ucf, linker,getEnv(q)); 
 314 bdemsky  1.1.2.1                  //Add mapping of call->class
 315 bdemsky  1.1.2.1                  cont_map.put(q,hclass);
 316 bdemsky  1.1.2.1                  //Schedule blocking method for transformation
 317 bdemsky  1.1.2.1                  scheduleMethods(q.method());
 318 bdemsky  1.1.2.1              }
 319 bdemsky  1.1.2.10             if (optimistic)
 320 bdemsky  1.1.2.10                 blocking.add(q);
 321 bdemsky  1.1.2.1              handleBlocking(q);
 322 bdemsky  1.1.2.1          } else
 323 bdemsky  1.1.2.1              handleNonBlocking(q);
 324 bdemsky  1.1.2.1      }
 325 bdemsky  1.1.2.1      
 326 bdemsky  1.1.2.1      private void addEdges(Quad q, Set dontfollow) {
 327 bdemsky  1.1.2.1          WorkSet done=new WorkSet();
 328 bdemsky  1.1.2.1          WorkSet todo=new WorkSet();
 329 bdemsky  1.1.2.1          todo.push(q);
 330 bdemsky  1.1.2.1          while (!todo.isEmpty()) {
 331 bdemsky  1.1.2.1              Quad nq=(Quad)todo.pop();
 332 bdemsky  1.1.2.1              done.add(nq);
 333 bdemsky  1.1.2.1              Quad cnq=(Quad)quadmap.get(nq);
 334 bdemsky  1.1.2.1              Quad[] next=nq.next();
 335 bdemsky  1.1.2.1              if (addedCall.contains(cnq)) {
 336 bdemsky  1.1.2.1                  //Handling call with additional call added to it
 337 bdemsky  1.1.2.1                  //0 edge is different...we want to link cnq.next(0) instead of cnqq
 338 bdemsky  1.1.2.1                  if (!done.contains(next[0]))
 339 bdemsky  1.1.2.1                      todo.push(next[0]);
 340 bdemsky  1.1.2.1                  Quad cn=(Quad)quadmap.get(next[0]);
 341 bdemsky  1.1.2.5                  //add the edge in [phi node]
 342 bdemsky  1.1.2.5                  Quad cnq2=cnq.next(0).next(0);
 343 bdemsky  1.1.2.1                  Quad.addEdge(cnq2,0,cn,nq.nextEdge(0).which_pred());
 344 bdemsky  1.1.2.1                  
 345 bdemsky  1.1.2.1                  //1 edge is as normal
 346 bdemsky  1.1.2.1                  if (!done.contains(next[1]))
 347 bdemsky  1.1.2.1                      todo.push(next[1]);
 348 bdemsky  1.1.2.1                  cn=(Quad)quadmap.get(next[1]);
 349 bdemsky  1.1.2.1                  //add the exception edge in
 350 bdemsky  1.1.2.1                  Quad.addEdge(cnq,1,cn,nq.nextEdge(1).which_pred());
 351 bdemsky  1.1.2.1              } else if (!dontfollow.contains(nq))
 352 bdemsky  1.1.2.10                 if (optimistic&&blocking.contains(nq)) {
 353 bdemsky  1.1.2.10                     //do 0 edge
 354 bdemsky  1.1.2.10                     if (!done.contains(next[0]))
 355 bdemsky  1.1.2.10                         todo.push(next[0]);
 356 bdemsky  1.1.2.10                     Quad cn0=(Quad)quadmap.get(next[0]);
 357 bdemsky  1.1.2.12                     if ((!((CALL)nq).method().getReturnType().isPrimitive())&&
 358 bdemsky  1.1.2.12                         (!((CALL)nq).method().getReturnType().equals(linker.forName("java.lang.Object")))) 
 359 bdemsky  1.1.2.12                         Quad.addEdge(cnq.next(0).next(0).next(1).next(0).next(0).next(0).next(1),0,cn0,nq.nextEdge(0).which_pred());
 360 bdemsky  1.1.2.12                     else
 361 bdemsky  1.1.2.12                         Quad.addEdge(cnq.next(0).next(0).next(1),0,cn0,nq.nextEdge(0).which_pred());
 362 bdemsky  1.1.2.10                     //do 1 edge
 363 bdemsky  1.1.2.10                     if (!done.contains(next[1]))
 364 bdemsky  1.1.2.10                         todo.push(next[1]);
 365 bdemsky  1.1.2.10                     Quad cn=(Quad)quadmap.get(next[1]);
 366 bdemsky  1.1.2.10                     Quad.addEdge(cnq,1,cn,nq.nextEdge(1).which_pred());
 367 bdemsky  1.1.2.10                 } else
 368 bdemsky  1.1.2.10                     for (int i=0;i<next.length;i++) {
 369 bdemsky  1.1.2.10                         //this quad was cloned
 370 bdemsky  1.1.2.10                         if (!done.contains(next[i]))
 371 bdemsky  1.1.2.10                             todo.push(next[i]);
 372 bdemsky  1.1.2.10                         Quad cn=(Quad)quadmap.get(next[i]);
 373 bdemsky  1.1.2.10                         //add the edge in
 374 bdemsky  1.1.2.10                         Quad.addEdge(cnq,i,cn,nq.nextEdge(i).which_pred());
 375 bdemsky  1.1.2.10                     }
 376 bdemsky  1.1.2.1          }
 377 bdemsky  1.1.2.1      }
 378 bdemsky  1.1.2.1  
 379 bdemsky  1.1.2.6      private HEADER buildEnvironmentExtracter(CALL q, int resumeexception){
 380 bdemsky  1.1.2.1          TempFactory tf=qf.tempFactory();
 381 bdemsky  1.1.2.1          //-----------------------------------------------------------------
 382 bdemsky  1.1.2.1          //Build HEADER
 383 bdemsky  1.1.2.1          
 384 bdemsky  1.1.2.1          Quad first=(Quad) quadmap.get(q.next(resumeexception));
 385 bdemsky  1.1.2.1          Temp oldrtemp=
 386 bdemsky  1.1.2.1              (resumeexception == 0) ?
 387 bdemsky  1.1.2.1              ((CALL)q).retval():((CALL)q).retex();
 388 bdemsky  1.1.2.1          Temp[] params=null;
 389 bdemsky  1.1.2.1          if (oldrtemp==null)
 390 bdemsky  1.1.2.1              params=new Temp[1];
 391 bdemsky  1.1.2.1          else {
 392 bdemsky  1.1.2.1              params=new Temp[2];
 393 bdemsky  1.1.2.1              params[1]=ctmap.tempMap(oldrtemp);
 394 bdemsky  1.1.2.1          }
 395 bdemsky  1.1.2.1          params[0]=tthis;
 396 bdemsky  1.1.2.1          HEADER header=new HEADER(qf,first);
 397 bdemsky  1.1.2.1          
 398 bdemsky  1.1.2.1          //-----------------------------------------------------------------
 399 bdemsky  1.1.2.1          //Build METHOD quad
 400 bdemsky  1.1.2.1          //
 401 bdemsky  1.1.2.28                     
 402 bdemsky  1.1.2.1          METHOD method=new METHOD(qf,first,params,1);
 403 bdemsky  1.1.2.1          Quad.addEdge(header,1,method,0);
 404 bdemsky  1.1.2.1          Temp tenv=new Temp(tf);
 405 bdemsky  1.1.2.1              
 406 bdemsky  1.1.2.1          //-----------------------------------------------------------------
 407 bdemsky  1.1.2.1          //Build GET quad for environment
 408 bdemsky  1.1.2.1          //
 409 bdemsky  1.1.2.1              
 410 bdemsky  1.1.2.1          GET get=
 411 bdemsky  1.1.2.1              new GET(qf,first,tenv,
 412 bdemsky  1.1.2.1                      hcode.getMethod().getDeclaringClass().getField("e"),
 413 bdemsky  1.1.2.1                      method.params(0));
 414 bdemsky  1.1.2.1          Quad.addEdge(method,0,get,0);
 415 bdemsky  1.1.2.1              
 416 bdemsky  1.1.2.1          //-----------------------------------------------------------------
 417 bdemsky  1.1.2.1          //GET Temp's out of environment
 418 bdemsky  1.1.2.1          //
 419 bdemsky  1.1.2.1          // assign each field in the Environment to the appropriate Temp
 420 bdemsky  1.1.2.1          // except for the assignment we want to suppress
 421 bdemsky  1.1.2.1          
 422 bdemsky  1.1.2.1          Temp suppress =
 423 bdemsky  1.1.2.1              (resumeexception == 0) ?
 424 bdemsky  1.1.2.1              ((CALL)q).retval() : ((CALL)q).retex();
 425 bdemsky  1.1.2.5          Quad qnext=q.next(resumeexception);
 426 bdemsky  1.1.2.5          Set livein;
 427 bdemsky  1.1.2.5          if (qnext.prevLength()!=1) {
 428 bdemsky  1.1.2.5              PHI phi=(PHI)qnext;
 429 bdemsky  1.1.2.5              livein=liveness.getLiveOut(qnext);
 430 bdemsky  1.1.2.5              int edge=q.nextEdge(resumeexception).which_pred();
 431 bdemsky  1.1.2.5              for (int j=0;j<phi.numPhis();j++) {
 432 bdemsky  1.1.2.5                  livein.remove(phi.dst(j));
 433 bdemsky  1.1.2.5              }
 434 bdemsky  1.1.2.5              for (int j=0;j<phi.numPhis();j++) {
 435 bdemsky  1.1.2.5                  livein.add(phi.src(j,edge));
 436 bdemsky  1.1.2.5              }
 437 bdemsky  1.1.2.5          } else
 438 bdemsky  1.1.2.5              livein=liveness.getLiveIn(qnext);
 439 bdemsky  1.1.2.5          Temp[] liveenv=getEnvTemps(q);
 440 bdemsky  1.1.2.1          Quad prev = get;
 441 bdemsky  1.1.2.1          HField[] envfields=getEnv(q).getDeclaredFields();
 442 bdemsky  1.1.2.2  
 443 bdemsky  1.1.2.1          //Build string of CONST's and GET's.
 444 bdemsky  1.1.2.1              
 445 cananian 1.8              for (Object tO : livein) {
 446 cananian 1.8                  Temp t = (Temp) tO;
 447 bdemsky  1.1.2.5              if (suppress == null || !suppress.equals(t)) {
 448 bdemsky  1.1.2.5                  Quad ng;
 449 bdemsky  1.1.2.5                  Temp ts=t;
 450 bdemsky  1.1.2.5                  if (typemap.typeMap(q, t)!=HClass.Void) {
 451 bdemsky  1.1.2.5                      for (int k=0;k<q.numSigmas();k++)
 452 bdemsky  1.1.2.5                          if (q.dst(k,resumeexception)==ts) {
 453 bdemsky  1.1.2.5                              ts=q.src(k);
 454 bdemsky  1.1.2.5                              break;
 455 bdemsky  1.1.2.5                          }
 456 bdemsky  1.1.2.5                      int index=-1;
 457 bdemsky  1.1.2.5                      for (int j=0;j<liveenv.length;j++)
 458 bdemsky  1.1.2.5                          if (liveenv[j]==ts) {
 459 bdemsky  1.1.2.5                              index=j;
 460 bdemsky  1.1.2.5                              break;
 461 bdemsky  1.1.2.5                          }
 462 bdemsky  1.1.2.5                      if (index==-1)
 463 bdemsky  1.1.2.5                          hc.print(new java.io.PrintWriter(System.out, true));
 464 cananian 1.3.2.1                      assert index!=-1 : "Couldn't find "+ts+ " of "+q+" in "+liveenv;
 465 bdemsky  1.1.2.5                      ng=new GET(qf, first, ctmap.tempMap(t),
 466 bdemsky  1.1.2.5                                 envfields[index], tenv);
 467 bdemsky  1.1.2.5                  } else {
 468 bdemsky  1.1.2.5                      ng=new CONST(qf, first, ctmap.tempMap(t),
 469 bdemsky  1.1.2.5                                   null, HClass.Void);
 470 bdemsky  1.1.2.5                  }
 471 bdemsky  1.1.2.1                  Quad.addEdge(prev, 0, ng, 0);
 472 bdemsky  1.1.2.1                  prev = ng;
 473 bdemsky  1.1.2.1              }
 474 bdemsky  1.1.2.1          }
 475 bdemsky  1.1.2.1          //-----------------------------------------------------------------
 476 bdemsky  1.1.2.1          // Typecast the argument to resume if necessary
 477 bdemsky  1.1.2.2  
 478 bdemsky  1.1.2.7          if (!((CALL)q).method().getReturnType().isPrimitive()&&
 479 bdemsky  1.1.2.7              !((CALL)q).method().getReturnType()
 480 bdemsky  1.1.2.18             .equals(linker.forName("java.lang.Object"))&&(resumeexception==0)) {
 481 bdemsky  1.1.2.6              Temp tresult=new Temp(tf), tnull=new Temp(tf), tresultn=new Temp(tf);
 482 bdemsky  1.1.2.6             
 483 bdemsky  1.1.2.6              CONST cn = new CONST(qf, first, tnull,null, HClass.Void);
 484 bdemsky  1.1.2.6              OPER op = new OPER(qf, first, Qop.ACMPEQ, tresultn,
 485 bdemsky  1.1.2.6                                 new Temp[]{ctmap.tempMap(((CALL)q).retval()), tnull});
 486 bdemsky  1.1.2.6              CJMP cjmp1=new CJMP(qf,first, tresultn, new Temp[0]);
 487 bdemsky  1.1.2.6              PHI phi=new PHI(qf, first, new Temp[0],2);
 488 bdemsky  1.1.2.6  
 489 bdemsky  1.1.2.6              INSTANCEOF io = new INSTANCEOF (qf, first,
 490 bdemsky  1.1.2.6                                              tresult, 
 491 bdemsky  1.1.2.6                                              ctmap.tempMap(((CALL)q).retval()),
 492 bdemsky  1.1.2.6                                              ((CALL)q).method().getReturnType());
 493 bdemsky  1.1.2.6              CJMP cjmp=new CJMP(qf, first, tresult, new Temp[0]);
 494 bdemsky  1.1.2.6                                 
 495 bdemsky  1.1.2.6              //String of quads
 496 bdemsky  1.1.2.6              Quad.addEdges(new Quad[] {prev, cn, op, cjmp1, io, cjmp});
 497 bdemsky  1.1.2.6              //Okay cases...
 498 bdemsky  1.1.2.6              Quad.addEdge(cjmp1,1,phi,0);
 499 bdemsky  1.1.2.6              Quad.addEdge(cjmp, 1, phi, 1);
 500 bdemsky  1.1.2.6              prev=phi;
 501 bdemsky  1.1.2.6  
 502 bdemsky  1.1.2.6              //Build Exception Thrower
 503 bdemsky  1.1.2.6              HClass HCex=linker.forName("java.lang.ClassCastException");
 504 bdemsky  1.1.2.6              Temp tex=new Temp(tf), tex2=new Temp(tf), tex3=new Temp(tf);
 505 bdemsky  1.1.2.21             //XXXX AIMAP [HEAP]
 506 bdemsky  1.1.2.6              NEW nquad=new NEW(qf, first, tex,
 507 bdemsky  1.1.2.6                                HCex);
 508 bdemsky  1.1.2.21             if (newai!=null)
 509 bdemsky  1.1.2.21                 newai.associate(nquad, new AllocationInformationMap.AllocationPropertiesImpl(true,
 510 salcianu 1.1.2.34                                                                                              false, false,false,
 511 salcianu 1.1.2.34                                                                                              false, // DEFAULT
 512 kkz      1.6                                                                                                   null, nquad.hclass(),
 513 kkz      1.6                                                                                                   false));
 514 bdemsky  1.1.2.6              Temp t1ex=new Temp(tf),t2=new Temp(tf);
 515 bdemsky  1.1.2.6              CALL call=new CALL(qf, first, HCex.getConstructor(new HClass[0]),
 516 bdemsky  1.1.2.6                                 new Temp[]{tex}, null, tex2, false, false,
 517 bdemsky  1.1.2.6                                 new Temp[][] {{t1ex,t2}},new Temp[] {tex});
 518 bdemsky  1.1.2.6              PHI phi2=new PHI(qf, first, new Temp[] {tex3}, new Temp[][]{{t1ex,tex2}},2);
 519 bdemsky  1.1.2.6              THROW qthrow=new THROW(qf, first, tex3);
 520 bdemsky  1.1.2.6  
 521 bdemsky  1.1.2.6              Quad.addEdge(cjmp,0,nquad,0);
 522 bdemsky  1.1.2.6              Quad.addEdges(new Quad[] {nquad,call, phi2,qthrow});
 523 bdemsky  1.1.2.6              Quad.addEdge(call,1,phi2,1);
 524 bdemsky  1.1.2.6              linkFooters.add(qthrow);
 525 bdemsky  1.1.2.1          }
 526 bdemsky  1.1.2.1          //-----------------------------------------------------------------
 527 bdemsky  1.1.2.1          //Link in header code to body of method
 528 bdemsky  1.1.2.10         int linkinedge=q.nextEdge(resumeexception).which_pred();
 529 bdemsky  1.1.2.10         if (first.prevEdge(linkinedge)==null)
 530 bdemsky  1.1.2.10             Quad.addEdge(prev,0,
 531 bdemsky  1.1.2.10                          first,
 532 bdemsky  1.1.2.10                          q.nextEdge(resumeexception).which_pred());
 533 bdemsky  1.1.2.10         else {
 534 bdemsky  1.1.2.10             PHI phi=new PHI(qf,first, new Temp[0],2);
 535 bdemsky  1.1.2.10             Quad.addEdge(prev,0,phi,0);
 536 bdemsky  1.1.2.11             int linkinedge2=q.nextEdge(resumeexception).which_succ();
 537 bdemsky  1.1.2.11             Quad.addEdge(first.prev(linkinedge),linkinedge2,phi,1);
 538 bdemsky  1.1.2.10             Quad.addEdge(phi,0,first,linkinedge);
 539 bdemsky  1.1.2.10         }
 540 bdemsky  1.1.2.1          return header;
 541 bdemsky  1.1.2.1      }
 542 bdemsky  1.1.2.1          
 543 bdemsky  1.1.2.1  
 544 bdemsky  1.1.2.1      /**Shrinks PHI's as needed.*/
 545 bdemsky  1.1.2.1      
 546 bdemsky  1.1.2.1      private void fixphis() {
 547 cananian 1.8              for (Object phiO : phiset) {
 548 cananian 1.8                  PHI phi = (PHI) phiO;
 549 bdemsky  1.1.2.1              for (int i=phi.arity()-1;i>=0;i--)
 550 bdemsky  1.1.2.1                  if (phi.prevEdge(i)==null) {
 551 bdemsky  1.1.2.1                      phi=phi.shrink(i);
 552 bdemsky  1.1.2.1                  }
 553 bdemsky  1.1.2.1          }
 554 bdemsky  1.1.2.1      }
 555 bdemsky  1.1.2.1      
 556 bdemsky  1.1.2.1      /**On some methods, we need to check to see if we are top level
 557 bdemsky  1.1.2.1       *so that we return instead of resume.*/
 558 bdemsky  1.1.2.1      
 559 bdemsky  1.1.2.1      private boolean needsCheck() {
 560 bdemsky  1.1.2.1          HMethod m=hc.getMethod();
 561 bdemsky  1.1.2.1          HClass hcl=m.getDeclaringClass();
 562 bdemsky  1.1.2.1          
 563 bdemsky  1.1.2.1          if (linker.forName("java.lang.Runnable").
 564 bdemsky  1.1.2.1              isSuperinterfaceOf(hcl)&&
 565 bdemsky  1.1.2.1              hcl.getMethod("run",new HClass[0]).equals(m))
 566 bdemsky  1.1.2.1              return true;
 567 bdemsky  1.1.2.1          if (m.equals(mroot))
 568 bdemsky  1.1.2.1              return true;
 569 bdemsky  1.1.2.1          return false;
 570 bdemsky  1.1.2.1      }
 571 bdemsky  1.1.2.1  
 572 bdemsky  1.1.2.1      private void buildReturnContinuation(Quad q, Temp retthrowtemp, boolean isReturn) {
 573 bdemsky  1.1.2.5          TempFactory tf=qf.tempFactory();
 574 bdemsky  1.1.2.1          //--------------------------------------------------------------------
 575 bdemsky  1.1.2.1          //build GET next Quad
 576 bdemsky  1.1.2.1          HClass hclass=hcode.getMethod().getDeclaringClass();
 577 bdemsky  1.1.2.1          HField hfield=hclass.getField("next");
 578 bdemsky  1.1.2.1          Temp tnext=new Temp(tf);
 579 bdemsky  1.1.2.5          GET get=new GET(qf,q,
 580 bdemsky  1.1.2.1                          tnext, hfield, tthis);
 581 bdemsky  1.1.2.1          
 582 bdemsky  1.1.2.1          //---------------------------------------------------------------------
 583 bdemsky  1.1.2.1          //We may need to add null check on next field
 584 bdemsky  1.1.2.1          //If null (ie run_Async, main method), we need to return instead
 585 bdemsky  1.1.2.1          //of calling resume
 586 bdemsky  1.1.2.2          Temp t21=null,t22=null;
 587 bdemsky  1.1.2.1          Quad nq=get;
 588 bdemsky  1.1.2.5          Temp retthrow=(retthrowtemp==null)?null:ctmap.tempMap(retthrowtemp);
 589 bdemsky  1.1.2.1          if (needsCheck()) {
 590 bdemsky  1.1.2.1              Temp tnull=new Temp(tf);
 591 bdemsky  1.1.2.1              CONST qconst=
 592 bdemsky  1.1.2.5                  new CONST(qf, q, tnull, null, HClass.Void);
 593 bdemsky  1.1.2.1              Quad.addEdge(nq,0,qconst,0);
 594 bdemsky  1.1.2.1              Temp tcomp=new Temp(tf);
 595 bdemsky  1.1.2.1              OPER qoper=
 596 bdemsky  1.1.2.5                  new OPER(qf,q,Qop.ACMPEQ,tcomp, 
 597 bdemsky  1.1.2.1                           new Temp[] {tnext, tnull});
 598 bdemsky  1.1.2.1              Quad.addEdge(qconst, 0, qoper, 0);
 599 bdemsky  1.1.2.2              //Build temps for SSI sigma function
 600 bdemsky  1.1.2.2              Temp t1=new Temp(tf),t2=new Temp(tf);
 601 bdemsky  1.1.2.2              CJMP cjmp=(isReturn&&hc.getMethod().getReturnType()==HClass.Void)?
 602 bdemsky  1.1.2.5                  new CJMP(qf, q, tcomp, new Temp[][]{{t1,t2}},
 603 bdemsky  1.1.2.2                  new Temp[]{tnext}):
 604 bdemsky  1.1.2.5                  new CJMP(qf, q, tcomp, new Temp[][]{{t1,t2},{t21=new Temp(tf),t22=new Temp(tf)}},
 605 bdemsky  1.1.2.5                  new Temp[]{tnext,retthrow});
 606 bdemsky  1.1.2.2              //Note SSI renaming
 607 bdemsky  1.1.2.2              tnext=t1;
 608 bdemsky  1.1.2.5              retthrow=t21;
 609 bdemsky  1.1.2.1              Quad.addEdge(qoper, 0, cjmp, 0);
 610 bdemsky  1.1.2.1              nq=cjmp;
 611 bdemsky  1.1.2.1          }
 612 bdemsky  1.1.2.2  
 613 bdemsky  1.1.2.1          //---------------------------------------------------------------------
 614 bdemsky  1.1.2.1          //Build the call to resume
 615 bdemsky  1.1.2.1              
 616 bdemsky  1.1.2.2          Temp retex1=new Temp(tf);
 617 bdemsky  1.1.2.1          CALL call=null;
 618 bdemsky  1.1.2.1          if (!isReturn) {
 619 bdemsky  1.1.2.1              HClass throwable=linker.forName("java.lang.Throwable");
 620 bdemsky  1.1.2.1              HMethod resume=hfield.getType().getMethod("exception",
 621 bdemsky  1.1.2.1                                                        new HClass[] {throwable});
 622 bdemsky  1.1.2.5              call=new CALL(qf, q, resume,
 623 bdemsky  1.1.2.5                            new Temp[] {tnext,retthrow},null,retex1,
 624 bdemsky  1.1.2.1                            true,false,new Temp[0]);
 625 bdemsky  1.1.2.1          } else if (hc.getMethod().getReturnType()!=HClass.Void) {
 626 bdemsky  1.1.2.1              HMethod resume=(hc.getMethod().getReturnType().isPrimitive())?
 627 bdemsky  1.1.2.1                  hfield.getType().getMethod("resume",
 628 bdemsky  1.1.2.1                                             new HClass[] {hc.getMethod().getReturnType()}):
 629 bdemsky  1.1.2.1                  hfield.getType().getMethod("resume",
 630 bdemsky  1.1.2.1                                             new HClass[] {linker.forName("java.lang.Object")});
 631 bdemsky  1.1.2.1              //***** Tailcall eventually
 632 bdemsky  1.1.2.5              call=new CALL(qf, q, resume,
 633 bdemsky  1.1.2.5                            new Temp[] {tnext,retthrow},null,retex1,
 634 bdemsky  1.1.2.1                            true,false,new Temp[0]);
 635 bdemsky  1.1.2.1          } else {
 636 bdemsky  1.1.2.1              HMethod resume=hfield.getType().getMethod("resume", new HClass[0]);
 637 bdemsky  1.1.2.1              //***** Tailcall eventually
 638 bdemsky  1.1.2.5              call=new CALL(qf, q, resume,
 639 bdemsky  1.1.2.2                            new Temp[] {tnext}, null, retex1,
 640 bdemsky  1.1.2.1                            true, false, new Temp[0]);
 641 bdemsky  1.1.2.1          }
 642 bdemsky  1.1.2.1              
 643 bdemsky  1.1.2.1          //---------------------------------------------------------------------
 644 bdemsky  1.1.2.1          //Build THROW and RETURN quads
 645 bdemsky  1.1.2.1          
 646 bdemsky  1.1.2.1          Quad.addEdge(nq,0,call,0);
 647 bdemsky  1.1.2.18         Temp retex=(isReturn||(!needsCheck()))?retex1:new Temp(tf);
 648 bdemsky  1.1.2.18         //Temp retex=retex1;
 649 bdemsky  1.1.2.5          THROW qthrow=new THROW(qf,q,retex);
 650 bdemsky  1.1.2.5          RETURN qreturn=new RETURN(qf,q,null);
 651 bdemsky  1.1.2.1          if (isReturn)
 652 bdemsky  1.1.2.1              Quad.addEdge(call,1,qthrow,0);
 653 bdemsky  1.1.2.1          else
 654 bdemsky  1.1.2.1              Quad.addEdge(call,0, qreturn,0);
 655 bdemsky  1.1.2.1          linkFooters.add(qthrow);
 656 bdemsky  1.1.2.1          linkFooters.add(qreturn);
 657 bdemsky  1.1.2.1          
 658 bdemsky  1.1.2.1          //---------------------------------------------------------------------
 659 bdemsky  1.1.2.1          //If top level [main or run] link in possible RETURN edges
 660 bdemsky  1.1.2.1          //otherwise just link in 0 edge of the call to resume
 661 bdemsky  1.1.2.1              
 662 bdemsky  1.1.2.1          if (needsCheck()) {
 663 bdemsky  1.1.2.5              PHI phi=isReturn?new PHI(qf, q, new Temp[0], 2):
 664 bdemsky  1.1.2.5                  new PHI(qf,q, new Temp[] {retex}, new Temp[][]{{t22,retex1}},2);
 665 bdemsky  1.1.2.1              Quad.addEdge(nq, 1, phi, 0);
 666 bdemsky  1.1.2.1              if (isReturn) {
 667 bdemsky  1.1.2.1                  Quad.addEdge(call,0,phi,1);
 668 bdemsky  1.1.2.1                  Quad.addEdge(phi,0,qreturn,0);
 669 bdemsky  1.1.2.1              } else {
 670 bdemsky  1.1.2.1                  Quad.addEdge(call,1,phi,1);
 671 bdemsky  1.1.2.1                  Quad.addEdge(phi,0,qthrow,0);
 672 bdemsky  1.1.2.1              }
 673 bdemsky  1.1.2.1          } else
 674 bdemsky  1.1.2.1              if (isReturn)
 675 bdemsky  1.1.2.1                  Quad.addEdge(call,0,qreturn,0);
 676 bdemsky  1.1.2.1              else
 677 bdemsky  1.1.2.1                  Quad.addEdge(call,1,qthrow,0);
 678 bdemsky  1.1.2.1          quadmap.put(q, get);
 679 bdemsky  1.1.2.1      }
 680 bdemsky  1.1.2.1      
 681 bdemsky  1.1.2.1      private void buildDoneContinuation(Quad q, Temp retthrowtemp, boolean isReturn) {
 682 bdemsky  1.1.2.5          TempFactory tf=qf.tempFactory();
 683 bdemsky  1.1.2.1          //---------------------------------------------------------------------
 684 bdemsky  1.1.2.1          //Build NEW temp for DoneContinuation
 685 bdemsky  1.1.2.1          
 686 bdemsky  1.1.2.1          HClass rettype=hc.getMethod().getReturnType();
 687 bdemsky  1.1.2.1          String pref = 
 688 bdemsky  1.1.2.1              ContBuilder.getPrefix(rettype);
 689 bdemsky  1.1.2.10         HClass continuation = optimistic?linker.forName("harpoon.Analysis.ContBuilder."+pref+"ContinuationOpt")
 690 bdemsky  1.1.2.10             :linker.forName
 691 bdemsky  1.1.2.1              ("harpoon.Analysis.ContBuilder." + pref + "DoneContinuation");
 692 bdemsky  1.1.2.1          Temp newt=new Temp(tf);
 693 bdemsky  1.1.2.21         //XXXX AIMAP [CURRENT THREAD]
 694 bdemsky  1.1.2.5          NEW newq=new NEW(qf,q,newt, continuation);
 695 bdemsky  1.1.2.21         if (newai!=null)
 696 salcianu 1.1.2.34             newai.associate(newq, new AllocationInformationMap.AllocationPropertiesImpl(true, false, true, false,
 697 salcianu 1.1.2.34                                                                                         false, // DEFAULT
 698 kkz      1.6                                                                                              null, newq.hclass(),
 699 kkz      1.6                                                                                              false));
 700 bdemsky  1.1.2.1          
 701 bdemsky  1.1.2.1          //---------------------------------------------------------------------
 702 bdemsky  1.1.2.1          //Build CALL to DoneContinuation constructor
 703 bdemsky  1.1.2.1  
 704 bdemsky  1.1.2.1          Temp retex=new Temp(tf);
 705 bdemsky  1.1.2.1          HClass ret=isReturn?
 706 bdemsky  1.1.2.1              (rettype.isPrimitive()?rettype:linker.forName("java.lang.Object"))
 707 bdemsky  1.1.2.1              :linker.forName("java.lang.Throwable");
 708 bdemsky  1.1.2.1          HConstructor constructor=(ret!=HClass.Void)?continuation.getConstructor(new HClass[]{ret}):
 709 bdemsky  1.1.2.1          continuation.getConstructor(new HClass[0]);
 710 bdemsky  1.1.2.1          CALL call;
 711 bdemsky  1.1.2.2          Temp t1=new Temp(tf),t2=new Temp(tf);
 712 bdemsky  1.1.2.1          if (retthrowtemp!=null) {
 713 bdemsky  1.1.2.1              //***** Tailcall eventually
 714 bdemsky  1.1.2.1              Temp nretval=ctmap.tempMap(retthrowtemp);
 715 bdemsky  1.1.2.5              call=new CALL(qf, q, constructor,
 716 bdemsky  1.1.2.1                            new Temp[] {newt,nretval}, null,retex,
 717 bdemsky  1.1.2.2                            false,false,new Temp[][]{{t1,t2}},new Temp[]{newt});
 718 bdemsky  1.1.2.1          } else {
 719 bdemsky  1.1.2.1              //***** Tailcall eventually
 720 bdemsky  1.1.2.5              call=new CALL(qf, q, constructor,
 721 bdemsky  1.1.2.1                            new Temp[] {newt}, null, retex,
 722 bdemsky  1.1.2.2                            false, false, new Temp[][]{{t1,t2}},new Temp[]{newt});
 723 bdemsky  1.1.2.1          }
 724 bdemsky  1.1.2.1  
 725 bdemsky  1.1.2.1          //---------------------------------------------------------------------
 726 bdemsky  1.1.2.1          //Add return and throw quads
 727 bdemsky  1.1.2.1              
 728 bdemsky  1.1.2.1          Quad.addEdge(newq,0,call,0);
 729 bdemsky  1.1.2.5          THROW qthrow=new THROW(qf,q,retex);
 730 bdemsky  1.1.2.1          
 731 bdemsky  1.1.2.1          Quad.addEdge(call,1,qthrow,0);
 732 bdemsky  1.1.2.5          RETURN qreturn=new RETURN(qf,q,t1);
 733 bdemsky  1.1.2.1          Quad.addEdge(call,0,qreturn,0);
 734 bdemsky  1.1.2.1          linkFooters.add(qthrow);
 735 bdemsky  1.1.2.1          linkFooters.add(qreturn);
 736 bdemsky  1.1.2.1          quadmap.put(q, newq);
 737 bdemsky  1.1.2.1      }
 738 bdemsky  1.1.2.1      
 739 bdemsky  1.1.2.8      /** isBlocking tells whether a given <code>CALL</code>
 740 bdemsky  1.1.2.8       *  is blocking or not.  Currently based on a class hierarchy
 741 bdemsky  1.1.2.8       *  analysis.*/
 742 bdemsky  1.1.2.1  
 743 bdemsky  1.1.2.1      private boolean isBlocking(CALL q) {
 744 bdemsky  1.1.2.1          HMethod hm=q.method();
 745 bdemsky  1.1.2.1          if (blockingcalls.contains(hm))
 746 bdemsky  1.1.2.1              return true;
 747 bdemsky  1.1.2.1          HClass bclass=hm.getDeclaringClass();
 748 bdemsky  1.1.2.1          Set hchilds=ch.children(bclass);
 749 bdemsky  1.1.2.1          Iterator childit=hchilds.iterator();
 750 bdemsky  1.1.2.1          while (childit.hasNext()) {
 751 bdemsky  1.1.2.1              try {
 752 bdemsky  1.1.2.1                  HClass child=(HClass)childit.next();
 753 bdemsky  1.1.2.1                  HMethod hmtest=child.getDeclaredMethod(hm.getName(),
 754 bdemsky  1.1.2.1                                                         hm.getParameterTypes());
 755 bdemsky  1.1.2.1                  if (blockingcalls.contains(hmtest))
 756 bdemsky  1.1.2.1                      return true;
 757 bdemsky  1.1.2.1              } catch (NoSuchMethodError e) {
 758 bdemsky  1.1.2.1              }
 759 bdemsky  1.1.2.1          }
 760 bdemsky  1.1.2.1          return false;
 761 bdemsky  1.1.2.1      }
 762 bdemsky  1.1.2.1  
 763 bdemsky  1.1.2.8      /** checkdoneothers sees that for a given call statement, that we've
 764 bdemsky  1.1.2.8       *  rewritten normal versions of any methods it might directly call.
 765 bdemsky  1.1.2.8       *  [meaning that we applied the swapTo and swapAdd substitutions.]*/
 766 bdemsky  1.1.2.8  
 767 bdemsky  1.1.2.8      private void checkdoneothers(CALL q) {
 768 bdemsky  1.1.2.8          HMethod ohm=q.method();
 769 bdemsky  1.1.2.1          //make sure we actually rewrite all methods that we can reach...
 770 bdemsky  1.1.2.1          if (!done_other.contains(ohm)) {
 771 bdemsky  1.1.2.1              HMethod hm=ohm;
 772 bdemsky  1.1.2.1              HClass hcl=hm.getDeclaringClass();
 773 bdemsky  1.1.2.1              if ((!linker.forName("java.lang.Thread").equals(hcl))||
 774 bdemsky  1.1.2.1                  (!hm.getName().equals("run_Async"))) {
 775 bdemsky  1.1.2.1                  Set classes=ch.children(hcl);
 776 bdemsky  1.1.2.1                  Iterator childit=classes.iterator();
 777 bdemsky  1.1.2.1                  HMethod parent=ohm;
 778 bdemsky  1.1.2.1                  while (childit.hasNext()|(hm!=null)) {
 779 bdemsky  1.1.2.1                      try {
 780 bdemsky  1.1.2.1                          if (hm==null) {
 781 bdemsky  1.1.2.1                              HClass child=(HClass)childit.next();
 782 bdemsky  1.1.2.1                              hm=child.getDeclaredMethod(parent.getName(),
 783 bdemsky  1.1.2.1                                                         parent.getParameterTypes());
 784 bdemsky  1.1.2.1                              if (done_other.contains(hm)) {
 785 bdemsky  1.1.2.1                                  hm=null;
 786 bdemsky  1.1.2.1                                  continue;
 787 bdemsky  1.1.2.1                              }
 788 bdemsky  1.1.2.1                          }
 789 bdemsky  1.1.2.1                      } catch (NoSuchMethodError e) {
 790 bdemsky  1.1.2.1                      }
 791 bdemsky  1.1.2.1                      if (hm!=null) {
 792 bdemsky  1.1.2.1                          other.add(hm);
 793 bdemsky  1.1.2.1                          hm=null;
 794 bdemsky  1.1.2.1                      }
 795 bdemsky  1.1.2.1                  }
 796 bdemsky  1.1.2.1              }
 797 bdemsky  1.1.2.1          }
 798 bdemsky  1.1.2.1      }
 799 bdemsky  1.1.2.8  
 800 bdemsky  1.1.2.8  
 801 bdemsky  1.1.2.26 
 802 bdemsky  1.1.2.26 
 803 bdemsky  1.1.2.26 
 804 bdemsky  1.1.2.8      /** scheduleMethods takes a given method that is being called,
 805 bdemsky  1.1.2.8       * either directly or by a start->run type connection, etc,
 806 bdemsky  1.1.2.8       * and schedules Asynchronous versions to be made.  This is currently
 807 bdemsky  1.1.2.8       * base on a class hierarchy scheme.
 808 bdemsky  1.1.2.8       */
 809 bdemsky  1.1.2.8  
 810 bdemsky  1.1.2.1      private void scheduleMethods(HMethod hm) {
 811 bdemsky  1.1.2.21         HMethod hmorig=hm;
 812 bdemsky  1.1.2.1          if (!old2new.containsKey(hm)) {
 813 bdemsky  1.1.2.1              HClass hcl=hm.getDeclaringClass();
 814 bdemsky  1.1.2.1              Set classes=ch.children(hcl);
 815 bdemsky  1.1.2.1              Iterator childit=classes.iterator();
 816 bdemsky  1.1.2.1              HMethod parent=hm;
 817 bdemsky  1.1.2.1              while (childit.hasNext()|(hm!=null)) {
 818 bdemsky  1.1.2.1                  try {
 819 bdemsky  1.1.2.1                      if (hm==null) {
 820 bdemsky  1.1.2.1                          HClass child=(HClass)childit.next();
 821 bdemsky  1.1.2.1                          hm=child.getDeclaredMethod(parent.getName(),
 822 bdemsky  1.1.2.1                                                     parent.getParameterTypes());
 823 bdemsky  1.1.2.1                          if (old2new.containsKey(hm)) {
 824 bdemsky  1.1.2.1                              hm=null;
 825 bdemsky  1.1.2.1                              continue;
 826 bdemsky  1.1.2.1                          }
 827 bdemsky  1.1.2.16                         if (!ch.callableMethods().contains(hm))
 828 bdemsky  1.1.2.16                             continue;
 829 bdemsky  1.1.2.16                         //don't need to build subclass methods that aren't
 830 bdemsky  1.1.2.16                         //callable
 831 bdemsky  1.1.2.1                      }
 832 bdemsky  1.1.2.1                      if (bm.swop(hm)!=null) {
 833 bdemsky  1.1.2.1                          //handle actual blocking call swapping
 834 bdemsky  1.1.2.1                          old2new.put(hm, bm.swop(hm));
 835 bdemsky  1.1.2.1                      } else {
 836 bdemsky  1.1.2.1                          if (hm.getName().compareTo("<init>")!=0) {
 837 bdemsky  1.1.2.1                              HCode toConvert=ucf.convert(hm);
 838 bdemsky  1.1.2.1                              if (toConvert!=null)
 839 bdemsky  1.1.2.1                                  async_todo.add(toConvert);
 840 bdemsky  1.1.2.26                             //else if (Modifier.isNative(hm.getModifiers())) {
 841 bdemsky  1.1.2.26                             //System.out.println("XXX:ERROR Native blocking: "+hm);
 842 bdemsky  1.1.2.26                             //System.exit(1);
 843 bdemsky  1.1.2.26                             //}
 844 bdemsky  1.1.2.1                              HMethod temp=AsyncCode.makeAsync(old2new, hm,
 845 bdemsky  1.1.2.16                                                              ucf,linker,optimistic);
 846 bdemsky  1.1.2.26                             if (Modifier.isNative(hm.getModifiers()))
 847 bdemsky  1.1.2.26                                 buildNativeWrapper(hm);
 848 bdemsky  1.1.2.26                             } else {
 849 bdemsky  1.1.2.1                              System.out.println("XXX:ERROR "+hm+" is blocking!");
 850 bdemsky  1.1.2.1                          }
 851 bdemsky  1.1.2.1                      }
 852 bdemsky  1.1.2.1                  } catch (NoSuchMethodError e) {
 853 bdemsky  1.1.2.1                  }
 854 bdemsky  1.1.2.1                  hm=null;
 855 bdemsky  1.1.2.1              }
 856 bdemsky  1.1.2.1          }
 857 bdemsky  1.1.2.1      }
 858 bdemsky  1.1.2.26 
 859 bdemsky  1.1.2.26     private void buildNativeWrapper(HMethod hm) {
 860 bdemsky  1.1.2.28         System.out.println("Building native wrapper for "+hm);
 861 bdemsky  1.1.2.26         HMethod newhm=(HMethod)old2new.get(hm);
 862 bdemsky  1.1.2.26         ContCodeSSI wrappercode=new ContCodeSSI(newhm);
 863 bdemsky  1.1.2.26         QuadFactory qf=wrappercode.getFactory();
 864 bdemsky  1.1.2.26         TempFactory tf=qf.tempFactory();
 865 bdemsky  1.1.2.26         HClass[] methodTypes=hm.getParameterTypes();
 866 bdemsky  1.1.2.27         Temp[] params=new Temp[methodTypes.length+(hm.isStatic()?0:1)];
 867 bdemsky  1.1.2.26         boolean isVirtual=hm.isStatic()?false:((hm.getName().equals("<init>")||
 868 bdemsky  1.1.2.26                                                 hm.getName().equals("<clinit>"))?false:true);
 869 bdemsky  1.1.2.26         boolean isVoid=hm.getReturnType()==HClass.Void;
 870 bdemsky  1.1.2.26         Temp retval=isVoid?null:new Temp(tf); 
 871 bdemsky  1.1.2.26         Temp retex=new Temp(tf);
 872 bdemsky  1.1.2.26         for (int i=0;i<params.length;i++)
 873 bdemsky  1.1.2.26             params[i]=new Temp(tf);
 874 bdemsky  1.1.2.26 
 875 bdemsky  1.1.2.26         HEADER header=new HEADER(qf,null);
 876 bdemsky  1.1.2.26         METHOD method=new METHOD(qf, null, params, 1);
 877 bdemsky  1.1.2.26         CALL call=new CALL(qf, null, hm, params,retval, retex,
 878 bdemsky  1.1.2.26                            isVirtual, false, new Temp[0]);
 879 bdemsky  1.1.2.26         FOOTER footer=new FOOTER(qf, null, 3);
 880 bdemsky  1.1.2.26         Quad.addEdge(header,0,footer,0);
 881 bdemsky  1.1.2.26         Quad.addEdge(header,1,method,0);
 882 bdemsky  1.1.2.26         Quad.addEdge(method,0,call,0);
 883 bdemsky  1.1.2.26         wrappercode.quadSet(header);
 884 bdemsky  1.1.2.26 
 885 bdemsky  1.1.2.26         if (optimistic) {
 886 bdemsky  1.1.2.26             Temp tnew=new Temp(tf);
 887 bdemsky  1.1.2.26             String pref = 
 888 bdemsky  1.1.2.26                 ContBuilder.getPrefix(hm.getReturnType());
 889 bdemsky  1.1.2.26             HClass contClass=linker.forName("harpoon.Analysis.ContBuilder."+pref+"ContinuationOpt");
 890 bdemsky  1.1.2.26             Temp retex2=new Temp(tf), retex3=new Temp(tf);
 891 bdemsky  1.1.2.26             Temp retval1=new Temp(tf),retval2=new Temp(tf);
 892 bdemsky  1.1.2.26 
 893 bdemsky  1.1.2.26             NEW qnew=new NEW(qf, null, tnew, contClass);
 894 bdemsky  1.1.2.28             CALL call2=new CALL(qf, null, contClass.getConstructor(isVoid?new HClass[0]:new HClass[]{hm.getReturnType()}), isVoid?new Temp[] {tnew}:new Temp[] {tnew, retval},
 895 bdemsky  1.1.2.28             null, retex2, false, false,new Temp[][]{{retval1,retval2}} ,new Temp[]{tnew});
 896 bdemsky  1.1.2.28             PHI phi=new PHI(qf, null, new Temp[] {retex3},new Temp[][] {{retex,retex2}}, 2);
 897 bdemsky  1.1.2.26             THROW qthrow=new THROW(qf, null, retex3);
 898 bdemsky  1.1.2.26             RETURN qreturn=new RETURN(qf, null, retval1);
 899 bdemsky  1.1.2.26             Quad.addEdge(call, 0, qnew,0);
 900 bdemsky  1.1.2.26             Quad.addEdge(call, 1, phi, 0);
 901 bdemsky  1.1.2.26             Quad.addEdge(qnew,0, call2,0);
 902 bdemsky  1.1.2.26             Quad.addEdge(call2,0,qreturn,0);
 903 bdemsky  1.1.2.26             Quad.addEdge(call2,1,phi,1);
 904 bdemsky  1.1.2.26             Quad.addEdge(phi,0,qthrow,0);
 905 bdemsky  1.1.2.26             Quad.addEdge(qreturn,0, footer,1);
 906 bdemsky  1.1.2.26             Quad.addEdge(qthrow,0,footer,2);
 907 bdemsky  1.1.2.26         } else {
 908 bdemsky  1.1.2.26             Temp tnew1=new Temp(tf),tnew2=new Temp(tf);
 909 bdemsky  1.1.2.26             String pref = 
 910 bdemsky  1.1.2.26                 ContBuilder.getPrefix(hm.getReturnType());
 911 bdemsky  1.1.2.26             HClass contClass=linker.forName("harpoon.Analysis.ContBuilder."+pref+"DoneContinuation");
 912 bdemsky  1.1.2.26             Temp retex1=new Temp(tf), retex2=new Temp(tf);
 913 bdemsky  1.1.2.26             Temp retexa=new Temp(tf), retexb=new Temp(tf);
 914 bdemsky  1.1.2.26             Temp retval1=new Temp(tf),retval2=new Temp(tf);
 915 bdemsky  1.1.2.26             Temp finret=new Temp(tf), finex=new Temp(tf);
 916 bdemsky  1.1.2.26             //Non Exception edge
 917 bdemsky  1.1.2.26             NEW qnew1=new NEW(qf, null, tnew1, contClass);
 918 bdemsky  1.1.2.28             CALL call21=new CALL(qf, null, contClass.getConstructor(isVoid?new HClass[0]:new HClass[]{hm.getReturnType()}), isVoid?new Temp[] {tnew1}:new Temp[] {tnew1, retval},
 919 bdemsky  1.1.2.28             null, retexa, false, false,new Temp[][]{{retval1,retval2}} ,new Temp[]{tnew1});
 920 bdemsky  1.1.2.26 
 921 bdemsky  1.1.2.26             //Exception edge
 922 bdemsky  1.1.2.26             NEW qnew2=new NEW(qf, null, tnew2, contClass);
 923 bdemsky  1.1.2.26             CALL call22=new CALL(qf, null, contClass.getConstructor(new HClass[]{linker.forName("java.lang.Throwable")}), new Temp[] {tnew2, retex},
 924 bdemsky  1.1.2.28             null, retexb, false, false,new Temp[][]{{retex1,retex2}} ,new Temp[]{tnew2});
 925 bdemsky  1.1.2.26 
 926 bdemsky  1.1.2.26 
 927 bdemsky  1.1.2.28             PHI phix=new PHI(qf, null, new Temp[] {finex},new Temp[][] {{retexa,retexb}}, 2);
 928 bdemsky  1.1.2.26 
 929 bdemsky  1.1.2.28             PHI phir=new PHI(qf, null, new Temp[] {finret},new Temp[][] {{retval1,retex1}}, 2);
 930 bdemsky  1.1.2.26             THROW qthrow=new THROW(qf, null, finex);
 931 bdemsky  1.1.2.26             RETURN qreturn=new RETURN(qf, null, finret);
 932 bdemsky  1.1.2.26 
 933 bdemsky  1.1.2.26             Quad.addEdge(call, 0, qnew1,0);
 934 bdemsky  1.1.2.26             Quad.addEdge(call, 1, qnew2, 0);
 935 bdemsky  1.1.2.26             Quad.addEdge(qnew1,0, call21,0);
 936 bdemsky  1.1.2.26             Quad.addEdge(qnew2,0, call22,0);
 937 bdemsky  1.1.2.26             Quad.addEdge(call21,0,phir,0);
 938 bdemsky  1.1.2.26             Quad.addEdge(call22,0,phir,1);
 939 bdemsky  1.1.2.26             Quad.addEdge(call21,1,phix,0);
 940 bdemsky  1.1.2.26             Quad.addEdge(call22,1,phix,1);
 941 bdemsky  1.1.2.26             Quad.addEdge(phir,0,qreturn,0);
 942 bdemsky  1.1.2.26             Quad.addEdge(phix,0,qthrow,0);
 943 bdemsky  1.1.2.26             Quad.addEdge(qreturn,0, footer,1);
 944 bdemsky  1.1.2.26             Quad.addEdge(qthrow,0,footer,2);
 945 bdemsky  1.1.2.26         }
 946 bdemsky  1.1.2.28         System.out.println("Adding "+newhm);
 947 bdemsky  1.1.2.26         ucf.put(newhm, wrappercode);
 948 bdemsky  1.1.2.28         wrappercode.print(new java.io.PrintWriter(System.out, true));
 949 bdemsky  1.1.2.26     }
 950 bdemsky  1.1.2.26 
 951 bdemsky  1.1.2.26 
 952 bdemsky  1.1.2.26 
 953 bdemsky  1.1.2.2      //---------------------------------------------------------
 954 bdemsky  1.1.2.2      //Need to ->SSI
 955 bdemsky  1.1.2.1      private void handleBlocking(CALL q) {
 956 bdemsky  1.1.2.5          TempFactory tf=qf.tempFactory();
 957 bdemsky  1.1.2.2          //---------------------------------------------------------------------
 958 bdemsky  1.1.2.2          //Build array of temps to pass into Enviroment's constructor
 959 bdemsky  1.1.2.2          //We need it to determine what temps we will need
 960 bdemsky  1.1.2.2          //Then build dst array for sigma function
 961 bdemsky  1.1.2.2  
 962 bdemsky  1.1.2.10         Temp srco[]=getEnvTemps(q);
 963 bdemsky  1.1.2.32 
 964 bdemsky  1.1.2.10         Temp src[]=map(ctmap,srco);
 965 bdemsky  1.1.2.24         Temp srcarray[]=q.src();
 966 bdemsky  1.1.2.30         Vector vsrc=new Vector(Arrays.asList(srco));
 967 bdemsky  1.1.2.25         if (optimistic) {
 968 bdemsky  1.1.2.30             Vector vsrc2=new Vector(Arrays.asList(srcarray));
 969 bdemsky  1.1.2.25             vsrc2.removeAll(vsrc);
 970 bdemsky  1.1.2.25             vsrc.addAll(vsrc2);
 971 bdemsky  1.1.2.25         }
 972 bdemsky  1.1.2.24         Temp[] csrc=new Temp[vsrc.size()];
 973 bdemsky  1.1.2.24         vsrc.copyInto(csrc);
 974 bdemsky  1.1.2.24         Temp[] src2=map(ctmap,csrc);
 975 bdemsky  1.1.2.24         
 976 bdemsky  1.1.2.2          Temp dst[][]=new Temp[src.length][2];
 977 bdemsky  1.1.2.24         Temp dst2[][]=new Temp[src2.length][2];
 978 bdemsky  1.1.2.24 
 979 bdemsky  1.1.2.24         for (int i=0;i<src2.length;i++) {
 980 bdemsky  1.1.2.10             boolean flag=true;
 981 bdemsky  1.1.2.10             if (optimistic)
 982 bdemsky  1.1.2.24                 for (int j=0;j<q.numSigmas();j++)
 983 bdemsky  1.1.2.24                     if (csrc[i]==srcarray[j])
 984 bdemsky  1.1.2.24                         if (flag) {
 985 bdemsky  1.1.2.24                             srcarray[j]=null;
 986 bdemsky  1.1.2.24                             dst2[i][0]=ctmap.tempMap(q.dst(j,0));
 987 bdemsky  1.1.2.24                             dst2[i][1]=ctmap.tempMap(q.dst(j,1));
 988 bdemsky  1.1.2.24                             if (i<src.length) {
 989 bdemsky  1.1.2.24                                 dst[i][0]=dst2[i][0];
 990 bdemsky  1.1.2.24                                 dst[i][1]=dst2[i][1];
 991 bdemsky  1.1.2.24                             }
 992 bdemsky  1.1.2.24                             flag=false;
 993 bdemsky  1.1.2.24                         }
 994 bdemsky  1.1.2.24             if (flag) {
 995 bdemsky  1.1.2.24                 dst2[i][0]=new Temp(tf);
 996 bdemsky  1.1.2.24                 dst2[i][1]=new Temp(tf);
 997 bdemsky  1.1.2.24                 if (i<src.length) {
 998 bdemsky  1.1.2.24                     dst[i][0]=dst2[i][0];
 999 bdemsky  1.1.2.24                     dst[i][1]=dst2[i][1];
1000 bdemsky  1.1.2.24                 }
1001 bdemsky  1.1.2.10             }
1002 bdemsky  1.1.2.2          }
1003 bdemsky  1.1.2.1          
1004 bdemsky  1.1.2.2          //--------------------------------------------------------------------
1005 bdemsky  1.1.2.1          //Rewrite the Blocking Call
1006 bdemsky  1.1.2.1          
1007 bdemsky  1.1.2.10         int numexc=5;
1008 bdemsky  1.1.2.10         int offset=0;
1009 bdemsky  1.1.2.10         if (!isCont) numexc--;
1010 bdemsky  1.1.2.10         if (optimistic) {
1011 bdemsky  1.1.2.10             numexc--;
1012 bdemsky  1.1.2.10             offset--;
1013 bdemsky  1.1.2.10         }
1014 bdemsky  1.1.2.10 
1015 bdemsky  1.1.2.10 
1016 bdemsky  1.1.2.2          Temp[] newt=map(ctmap, q.params());
1017 bdemsky  1.1.2.2          Temp pretex=new Temp(tf);
1018 bdemsky  1.1.2.10         Temp[] retex=new Temp[numexc];
1019 bdemsky  1.1.2.10         for (int i=0;i<numexc;i++)
1020 bdemsky  1.1.2.2              retex[i]=new Temp(tf);
1021 bdemsky  1.1.2.2  
1022 bdemsky  1.1.2.2          Temp retcont=new Temp(tf);
1023 bdemsky  1.1.2.1          HMethod calleemethod=(HMethod)old2new.get(q.method());
1024 bdemsky  1.1.2.2  
1025 bdemsky  1.1.2.10         CALL call=new CALL(qf,q,
1026 bdemsky  1.1.2.1                             calleemethod, newt,
1027 bdemsky  1.1.2.10                            retcont,optimistic?ctmap.tempMap(q.retex()):retex[0],
1028 bdemsky  1.1.2.10                            q.isVirtual(), q.isTailCall(),
1029 bdemsky  1.1.2.24                            dst2,src2);
1030 bdemsky  1.1.2.10         Quad cnext=call;
1031 bdemsky  1.1.2.1          
1032 bdemsky  1.1.2.1          //---------------------------------------------------------------------
1033 bdemsky  1.1.2.1          //Build phi node for exception handler
1034 bdemsky  1.1.2.10 
1035 bdemsky  1.1.2.10 
1036 bdemsky  1.1.2.10         PHI phi=new PHI(qf, q, new Temp[]{pretex}, new Temp[][]{retex}, numexc);
1037 bdemsky  1.1.2.10 
1038 bdemsky  1.1.2.10         if (!optimistic) {
1039 bdemsky  1.1.2.10             Quad.addEdge(cnext,1,phi,0);
1040 bdemsky  1.1.2.10         } else {
1041 bdemsky  1.1.2.10             Temp isdone=new Temp(tf);
1042 bdemsky  1.1.2.10             HField donefield=calleemethod.getReturnType().getField("done");
1043 bdemsky  1.1.2.10             GET get=new GET(qf,q,isdone,donefield,retcont);
1044 bdemsky  1.1.2.10             CJMP cjmp=new CJMP(qf,q,isdone,new Temp[0]);
1045 bdemsky  1.1.2.10             Quad.addEdge(cnext,0,get,0);
1046 bdemsky  1.1.2.10             Quad.addEdge(get,0,cjmp,0);
1047 bdemsky  1.1.2.10             if (q.retval()!=null) {
1048 bdemsky  1.1.2.10                 HField resultfield=calleemethod.getReturnType().getField("result");
1049 bdemsky  1.1.2.10                 GET get2=new GET(qf,q, ctmap.tempMap(q.retval())  ,resultfield,retcont);
1050 bdemsky  1.1.2.10                 Quad.addEdge(cjmp,1,get2,0);
1051 bdemsky  1.1.2.12                 if ((!q.method().getReturnType().isPrimitive())&&
1052 bdemsky  1.1.2.12                     (!q.method().getReturnType().equals(linker.forName("java.lang.Object")))) {
1053 bdemsky  1.1.2.12                     //Have to TYPECAST
1054 bdemsky  1.1.2.12                     Temp tresult=new Temp(tf), tnull=new Temp(tf), tresultn=new Temp(tf);
1055 bdemsky  1.1.2.12                     
1056 bdemsky  1.1.2.12                     CONST cn = new CONST(qf, q, tnull,null, HClass.Void);
1057 bdemsky  1.1.2.12                     OPER op = new OPER(qf, q, Qop.ACMPEQ, tresultn,
1058 bdemsky  1.1.2.12                                        new Temp[]{ctmap.tempMap(((CALL)q).retval()), tnull});
1059 bdemsky  1.1.2.12                     CJMP cjmp1=new CJMP(qf,q, tresultn, new Temp[0]);
1060 bdemsky  1.1.2.12                     PHI phia=new PHI(qf, q, new Temp[0],2);
1061 bdemsky  1.1.2.12 
1062 bdemsky  1.1.2.12                     INSTANCEOF io = new INSTANCEOF (qf, q,
1063 bdemsky  1.1.2.12                                                     tresult, 
1064 bdemsky  1.1.2.12                                                     ctmap.tempMap(q.retval()),
1065 bdemsky  1.1.2.12                                                     ((CALL)q).method().getReturnType());
1066 bdemsky  1.1.2.12                     CJMP cjmpa=new CJMP(qf, q, tresult, new Temp[0]);
1067 bdemsky  1.1.2.12                     
1068 bdemsky  1.1.2.12                     //String of quads
1069 bdemsky  1.1.2.12                     Quad.addEdges(new Quad[] {get2, cn, op, cjmp1, io, cjmpa});
1070 bdemsky  1.1.2.12                     //Okay cases...
1071 bdemsky  1.1.2.12                     Quad.addEdge(cjmp1,1,phia,0);
1072 bdemsky  1.1.2.12                     Quad.addEdge(cjmpa, 1, phia, 1);
1073 bdemsky  1.1.2.12 
1074 bdemsky  1.1.2.12                     //Build Exception Thrower
1075 bdemsky  1.1.2.12                     HClass HCex=linker.forName("java.lang.ClassCastException");
1076 bdemsky  1.1.2.12                     Temp tex=new Temp(tf), tex2=new Temp(tf), tex3=new Temp(tf);
1077 bdemsky  1.1.2.21                     //XXXX AIMAP [HEAP]
1078 bdemsky  1.1.2.12                     NEW nquad=new NEW(qf, q, tex,
1079 bdemsky  1.1.2.12                                       HCex);
1080 bdemsky  1.1.2.21                     if (newai!=null)
1081 salcianu 1.1.2.34                         newai.associate(nquad, new AllocationInformationMap.AllocationPropertiesImpl(true, false, false, false,
1082 salcianu 1.1.2.34                                                                                                      false, // DEFAULT
1083 kkz      1.6                                                                                                           null, nquad.hclass(),
1084 kkz      1.6                                                                                                           false));
1085 bdemsky  1.1.2.12                     Temp t1ex=new Temp(tf),t2=new Temp(tf);
1086 bdemsky  1.1.2.12                     CALL calla=new CALL(qf, q, HCex.getConstructor(new HClass[0]),
1087 bdemsky  1.1.2.12                                        new Temp[]{tex}, null, tex2, false, false,
1088 bdemsky  1.1.2.12                                        new Temp[][] {{t1ex,t2}},new Temp[] {tex});
1089 bdemsky  1.1.2.12                     PHI phi2=new PHI(qf, q, new Temp[] {tex3}, new Temp[][]{{t1ex,tex2}},2);
1090 bdemsky  1.1.2.12                     THROW qthrow=new THROW(qf, q, tex3);
1091 bdemsky  1.1.2.12                     
1092 bdemsky  1.1.2.12                     Quad.addEdge(cjmpa,0,nquad,0);
1093 bdemsky  1.1.2.12                     Quad.addEdges(new Quad[] {nquad,calla, phi2,qthrow});
1094 bdemsky  1.1.2.12                     Quad.addEdge(calla,1,phi2,1);
1095 bdemsky  1.1.2.12                     linkFooters.add(qthrow);
1096 bdemsky  1.1.2.12                 } 
1097 bdemsky  1.1.2.12 
1098 bdemsky  1.1.2.10             } else {
1099 bdemsky  1.1.2.10                 NOP nop=new NOP(qf,q);
1100 bdemsky  1.1.2.10                 Quad.addEdge(cjmp,1,nop,0);
1101 bdemsky  1.1.2.10             }
1102 bdemsky  1.1.2.10             cnext=cjmp;
1103 bdemsky  1.1.2.10         }
1104 bdemsky  1.1.2.2                  
1105 bdemsky  1.1.2.1          //---------------------------------------------------------------------
1106 bdemsky  1.1.2.2          //Build array for initializer
1107 bdemsky  1.1.2.2  
1108 bdemsky  1.1.2.1          Temp tenv=new Temp(tf);
1109 bdemsky  1.1.2.2          Temp params[]=new Temp[src.length+1];
1110 bdemsky  1.1.2.1          params[0]=tenv;
1111 bdemsky  1.1.2.2          for (int i=0;i<src.length;i++)
1112 bdemsky  1.1.2.2              params[i+1]=dst[i][0];
1113 bdemsky  1.1.2.14         if (recycle&&isCont&&(q==origCall)) {
1114 bdemsky  1.1.2.14             //We can recycle!!!
1115 bdemsky  1.1.2.14             //tthis has the temp for our object
1116 bdemsky  1.1.2.14             Temp tretex=new Temp(tf);
1117 bdemsky  1.1.2.14             HField envfield=hcode.getMethod().getDeclaringClass().getField("e");
1118 bdemsky  1.1.2.14             GET get1=new GET(qf,q,tenv,envfield,tthis);
1119 bdemsky  1.1.2.14             HClass[] envparams=getEnv(q).getConstructors()[0].getParameterTypes();
1120 bdemsky  1.1.2.14             HMethod hrecycle=getEnv(q).getDeclaredMethod("recycle", envparams);
1121 bdemsky  1.1.2.14             CALL callrec=new CALL(qf,q, hrecycle, params, null,tretex,
1122 bdemsky  1.1.2.14                                   true,false, new Temp[0]);
1123 bdemsky  1.1.2.15 
1124 bdemsky  1.1.2.15             PHI qphi=new PHI(qf,q,new Temp[0],2);
1125 bdemsky  1.1.2.15             
1126 bdemsky  1.1.2.15 
1127 bdemsky  1.1.2.15 
1128 bdemsky  1.1.2.15             String pref = 
1129 bdemsky  1.1.2.15                 ContBuilder.getPrefix(q.method().getReturnType());
1130 bdemsky  1.1.2.15             HClass[] nextarray=
1131 bdemsky  1.1.2.15                 new HClass[] {linker.forName("harpoon.Analysis.ContBuilder."+pref+"ResultContinuation")};
1132 bdemsky  1.1.2.15             HMethod setnextmethod=
1133 bdemsky  1.1.2.15                 calleemethod.getReturnType().getMethod("setNext",nextarray);
1134 cananian 1.3.2.1              assert setnextmethod!=null : "no setNext method found";
1135 bdemsky  1.1.2.15             CALL callrec2=new CALL(qf, q,
1136 bdemsky  1.1.2.15                                    setnextmethod, new Temp[] {retcont, tthis},
1137 bdemsky  1.1.2.15                                    null, tretex, true, false, 
1138 bdemsky  1.1.2.15                                    new Temp[0]);
1139 bdemsky  1.1.2.15             RETURN qret=new RETURN(qf, q, null);
1140 bdemsky  1.1.2.15             THROW qthrow=new THROW(qf,q,tretex);
1141 bdemsky  1.1.2.15         
1142 bdemsky  1.1.2.14             Quad.addEdge(cnext,0,get1,0);
1143 bdemsky  1.1.2.14             Quad.addEdge(get1,0,callrec,0);
1144 bdemsky  1.1.2.15             Quad.addEdge(callrec,0,callrec2,0);
1145 bdemsky  1.1.2.15             Quad.addEdge(callrec2,0,qret,0);
1146 bdemsky  1.1.2.15             Quad.addEdge(callrec,1,qphi,0);
1147 bdemsky  1.1.2.15             Quad.addEdge(callrec2,1,qphi,1);
1148 bdemsky  1.1.2.15             Quad.addEdge(qphi,0,qthrow,0);
1149 bdemsky  1.1.2.14             linkFooters.add(qthrow);
1150 bdemsky  1.1.2.14             linkFooters.add(qret);
1151 bdemsky  1.1.2.19             if (!optimistic) {
1152 bdemsky  1.1.2.19                 //toss away the old phi...
1153 bdemsky  1.1.2.19                 THROW throwq=new THROW(qf,q,retex[0]);    
1154 bdemsky  1.1.2.19                 Quad.addEdge(cnext,1,throwq,0);
1155 bdemsky  1.1.2.19                 linkFooters.add(throwq);
1156 bdemsky  1.1.2.19             }
1157 bdemsky  1.1.2.14         } else { 
1158 bdemsky  1.1.2.14             //---------------------------------------------------------------------
1159 bdemsky  1.1.2.14             //Build Environment NEW & CALL to init
1160 bdemsky  1.1.2.14             HClass env=getEnv(q);
1161 bdemsky  1.1.2.21             //XXXXXXXXXX
1162 bdemsky  1.1.2.21             //AIMAP[Current Thread]
1163 bdemsky  1.1.2.14             NEW envq=new NEW(qf, q, tenv, env);
1164 bdemsky  1.1.2.21             if (newai!=null)
1165 salcianu 1.1.2.34                 newai.associate(envq, new AllocationInformationMap.AllocationPropertiesImpl(true, false, true, false,
1166 salcianu 1.1.2.34                                                                                             false, // DEFAULT
1167 kkz      1.6                                                                                                  null, envq.hclass(),
1168 kkz      1.6                                                                                                  false));
1169 bdemsky  1.1.2.14             Quad.addEdge(cnext,0,envq,0);
1170 bdemsky  1.1.2.14             Temp t1=new Temp(tf),t2=new Temp(tf),t21=new Temp(tf),t22=new Temp(tf);
1171 bdemsky  1.1.2.14             CALL callenv=new CALL(qf, q, env.getConstructors()[0],
1172 bdemsky  1.1.2.14                                   params, null, retex[1+offset], false, false, 
1173 bdemsky  1.1.2.14                                   new Temp[][]{{t1,t2},{t21,t22}},
1174 bdemsky  1.1.2.14                                   new Temp[] {tenv,retcont});
1175 bdemsky  1.1.2.14             tenv=t1;retcont=t21;
1176 bdemsky  1.1.2.14             Quad.addEdge(envq,0,callenv,0);
1177 bdemsky  1.1.2.14             Quad.addEdge(callenv,1,phi,1+offset);
1178 bdemsky  1.1.2.14             
1179 bdemsky  1.1.2.14             //---------------------------------------------------------------------
1180 bdemsky  1.1.2.14             //Build Continuation NEW & CALL to init
1181 bdemsky  1.1.2.14             
1182 bdemsky  1.1.2.14             Temp tcont=new Temp(tf);
1183 bdemsky  1.1.2.14             HClass contclass=(HClass)cont_map.get(q);
1184 bdemsky  1.1.2.21             //XXX AIMAP[Current Thread]
1185 bdemsky  1.1.2.14             NEW newc=new NEW(qf, q, tcont, contclass);
1186 bdemsky  1.1.2.21             if (newai!=null)
1187 salcianu 1.1.2.34                 newai.associate(newc, new AllocationInformationMap.AllocationPropertiesImpl(true, false, true,false,
1188 salcianu 1.1.2.34                                                                                             false, // DEFAULT
1189 kkz      1.6                                                                                                  null, newc.hclass(),
1190 kkz      1.6                                                                                                  false));
1191 bdemsky  1.1.2.14             Quad.addEdge(callenv,0,newc,0);
1192 bdemsky  1.1.2.14             //  HClass environment=linker.forName("harpoon.Analysis.EnvBuilder.Environment");
1193 bdemsky  1.1.2.14             HConstructor call2const=contclass.getConstructor(new HClass[]{
1194 bdemsky  1.1.2.14                 env});
1195 bdemsky  1.1.2.14             Temp nt1=new Temp(tf),nt2=new Temp(tf),nt21=new Temp(tf),nt22=new Temp(tf);
1196 bdemsky  1.1.2.14             CALL call2=new CALL(qf,q,
1197 bdemsky  1.1.2.14                                 call2const,
1198 bdemsky  1.1.2.14                                 new Temp[] {tcont, tenv}, null, retex[2+offset], 
1199 bdemsky  1.1.2.14                                 false, false, new Temp[][]{{nt1,nt2},{nt21,nt22}},
1200 bdemsky  1.1.2.14                                 new Temp[]{tcont,retcont});
1201 bdemsky  1.1.2.14             tcont=nt1;retcont=nt21;
1202 bdemsky  1.1.2.14             Quad.addEdge(newc,0,call2,0);
1203 bdemsky  1.1.2.14             Quad.addEdge(call2,1,phi,2+offset);
1204 bdemsky  1.1.2.14             
1205 bdemsky  1.1.2.14             //---------------------------------------------------------------------
1206 bdemsky  1.1.2.14             //Link new Continuation onto Continuation returned by blocking call
1207 bdemsky  1.1.2.14             String pref = 
1208 bdemsky  1.1.2.14                 ContBuilder.getPrefix(q.method().getReturnType());
1209 bdemsky  1.1.2.14             HClass[] nextarray=
1210 bdemsky  1.1.2.14                 new HClass[] {linker.forName("harpoon.Analysis.ContBuilder."+pref+"ResultContinuation")};
1211 bdemsky  1.1.2.14             HMethod setnextmethod=
1212 bdemsky  1.1.2.14                 calleemethod.getReturnType().getMethod("setNext",nextarray);
1213 cananian 1.3.2.1              assert setnextmethod!=null : "no setNext method found";
1214 bdemsky  1.1.2.14             Temp nnt1=new Temp(tf),nnt2=new Temp(tf);
1215 bdemsky  1.1.2.14             CALL call3=new CALL(qf, q,
1216 bdemsky  1.1.2.14                                 setnextmethod, new Temp[] {retcont, tcont},
1217 bdemsky  1.1.2.14                                 null, retex[3+offset], true, false, 
1218 bdemsky  1.1.2.2                              new Temp[][]{{nnt1,nnt2}},new Temp[]{tcont});
1219 bdemsky  1.1.2.14             tcont=nnt1;
1220 bdemsky  1.1.2.14             Quad.addEdge(call2, 0, call3, 0);
1221 bdemsky  1.1.2.14             Quad.addEdge(call3, 1, phi, 3+offset);
1222 bdemsky  1.1.2.14             
1223 bdemsky  1.1.2.14             
1224 bdemsky  1.1.2.14             //---------------------------------------------------------------------
1225 bdemsky  1.1.2.14             //Two possibilities:
1226 bdemsky  1.1.2.14             //1)  We are a continuation, so we want to do a setNext(this.next)
1227 bdemsky  1.1.2.14             //2)  We are a Async method, so we want to return continuation
1228 bdemsky  1.1.2.14             
1229 bdemsky  1.1.2.14             if (isCont) {
1230 bdemsky  1.1.2.14                 Temp tnext=new Temp(tf);
1231 bdemsky  1.1.2.14                 HClass hclass=hcode.getMethod().getDeclaringClass();
1232 bdemsky  1.1.2.14                 HField hfield=hclass.getField("next");
1233 bdemsky  1.1.2.14                 GET get=new GET(qf,q,
1234 bdemsky  1.1.2.14                                 tnext, hfield, tthis);
1235 bdemsky  1.1.2.14                 Quad.addEdge(call3,0,get,0);
1236 bdemsky  1.1.2.14                 String pref2 =
1237 bdemsky  1.1.2.14                     ContBuilder.getPrefix(hc.getMethod().getReturnType());
1238 bdemsky  1.1.2.14                 HMethod setnextmethod2=
1239 bdemsky  1.1.2.14                     contclass.getMethod("setNext",
1240 bdemsky  1.1.2.14                                         new HClass[] {linker.forName("harpoon.Analysis.ContBuilder."+pref2+"ResultContinuation")});
1241 cananian 1.3.2.1                  assert setnextmethod2!=null : "no setNext method found";
1242 bdemsky  1.1.2.14                 CALL call4=new CALL(qf, q,
1243 bdemsky  1.1.2.14                                     setnextmethod2, new Temp[] {tcont, tnext},
1244 bdemsky  1.1.2.14                                     null, retex[4+offset], true, false, new Temp[0]);
1245 bdemsky  1.1.2.14                 Quad.addEdge(get,0,call4,0);
1246 bdemsky  1.1.2.14                 Quad.addEdge(call4,1,phi,4+offset);
1247 bdemsky  1.1.2.14                 RETURN returnq=new RETURN(qf, q, null);
1248 bdemsky  1.1.2.14                 Quad.addEdge(call4,0,returnq,0);
1249 bdemsky  1.1.2.14                 linkFooters.add(returnq);
1250 bdemsky  1.1.2.14             } else {
1251 bdemsky  1.1.2.14                 RETURN returnq=new RETURN(qf,q,tcont);
1252 bdemsky  1.1.2.14                 Quad.addEdge(call3, 0, returnq,0);
1253 bdemsky  1.1.2.14                 linkFooters.add(returnq);
1254 bdemsky  1.1.2.14             }
1255 bdemsky  1.1.2.14             //---------------------------------------------------------------
1256 bdemsky  1.1.2.14             //Do THROW of exceptions from phi node
1257 bdemsky  1.1.2.14             
1258 bdemsky  1.1.2.14             THROW throwq=new THROW(qf,q,pretex);    
1259 bdemsky  1.1.2.14             Quad.addEdge(phi,0,throwq,0);
1260 bdemsky  1.1.2.14             linkFooters.add(throwq);
1261 bdemsky  1.1.2.14         }       //end *******
1262 bdemsky  1.1.2.1          quadmap.put(q,call);
1263 bdemsky  1.1.2.10         if (optimistic)
1264 bdemsky  1.1.2.10             followchildren=true;
1265 bdemsky  1.1.2.10         else
1266 bdemsky  1.1.2.10             followchildren=false;
1267 bdemsky  1.1.2.1      }
1268 bdemsky  1.1.2.5      //Knows about SSI
1269 bdemsky  1.1.2.5      private Temp[] getEnvTemps(CALL q) {
1270 bdemsky  1.1.2.5          Set liveoutx = liveness.getLiveOut(q);
1271 bdemsky  1.1.2.5          Set livein = liveness.getLiveIn(q);
1272 bdemsky  1.1.2.5          WorkSet env=new WorkSet();
1273 bdemsky  1.1.2.5          for (Iterator ii=liveoutx.iterator();ii.hasNext();) {
1274 bdemsky  1.1.2.5              boolean search=true;
1275 bdemsky  1.1.2.5              Temp t=(Temp)ii.next();
1276 bdemsky  1.1.2.5              for (int i=0;(i<q.arity())&&search;i++)
1277 bdemsky  1.1.2.5                  for (int j=0;j<q.numSigmas();j++) {
1278 bdemsky  1.1.2.5                      if (q.dst(j,i)==t) {
1279 bdemsky  1.1.2.5                          if (typemap.typeMap(q,t)!=HClass.Void) {
1280 bdemsky  1.1.2.5                              env.add(q.src(j));
1281 bdemsky  1.1.2.5                          }
1282 bdemsky  1.1.2.5                          search=false;
1283 bdemsky  1.1.2.5                          break;
1284 bdemsky  1.1.2.5                      }
1285 bdemsky  1.1.2.5                  }
1286 bdemsky  1.1.2.5              if (search)
1287 bdemsky  1.1.2.5                  if (livein.contains(t)) {
1288 bdemsky  1.1.2.32                     if (typemap.typeMap(q,t)!=HClass.Void)
1289 bdemsky  1.1.2.32                         env.add(t);
1290 bdemsky  1.1.2.5                  }
1291 bdemsky  1.1.2.2          }
1292 bdemsky  1.1.2.5  
1293 bdemsky  1.1.2.5          Temp [] params = (Temp[]) env.toArray(new Temp[0]);
1294 bdemsky  1.1.2.5          Collections.sort(Arrays.asList(params));
1295 bdemsky  1.1.2.2          return params;
1296 bdemsky  1.1.2.2      }
1297 bdemsky  1.1.2.1      
1298 bdemsky  1.1.2.1      private void handleNonBlocking(CALL q) {
1299 bdemsky  1.1.2.1          followchildren=true;
1300 bdemsky  1.1.2.5          TempFactory tf=qf.tempFactory();
1301 bdemsky  1.1.2.1          //need to check if swop necessary
1302 bdemsky  1.1.2.1          if (swapTo(q.method())!=null) {
1303 bdemsky  1.1.2.1              //need to swop this method for replacement
1304 bdemsky  1.1.2.5              quadmap.put(q,new CALL(qf, q, swapTo(q.method()),
1305 bdemsky  1.1.2.2                                     map(ctmap, q.params()),
1306 bdemsky  1.1.2.1                                     (q.retval()==null)?null:ctmap.tempMap(q.retval()),
1307 bdemsky  1.1.2.1                                     (q.retex()==null)?null:ctmap.tempMap(q.retex()), q.isVirtual(),
1308 bdemsky  1.1.2.2                                     q.isTailCall(), map(ctmap, q.dst()),
1309 bdemsky  1.1.2.2                                     map(ctmap, q.src())));
1310 bdemsky  1.1.2.1          } else if (swapAdd(q.method())!=null) {
1311 bdemsky  1.1.2.1              //need to add an additional call [for makeAsync's, etc]
1312 bdemsky  1.1.2.2  
1313 bdemsky  1.1.2.5              CALL cq=(CALL)q.clone(qf, ctmap);
1314 bdemsky  1.1.2.5              int index=-1;
1315 bdemsky  1.1.2.5              for (int i=0;i<q.numSigmas();i++)
1316 bdemsky  1.1.2.5                  if (q.src(i)==q.params(0))
1317 bdemsky  1.1.2.5                      index=i;
1318 bdemsky  1.1.2.1              Temp retex=new Temp(tf);
1319 bdemsky  1.1.2.5              if (index==-1)
1320 bdemsky  1.1.2.5                  stillokay=false;
1321 bdemsky  1.1.2.5              Temp t=(index==-1)?ctmap.tempMap(q.params(0)):ctmap.tempMap(q.dst(index,0));
1322 bdemsky  1.1.2.5              CALL nc=new CALL(qf, q,
1323 bdemsky  1.1.2.1                               swapAdd(q.method()), 
1324 bdemsky  1.1.2.5                               new Temp[]{t},
1325 bdemsky  1.1.2.5                               null, retex, true, false, new Temp[0]);
1326 bdemsky  1.1.2.1              Quad.addEdge(cq,0,nc, 0);
1327 bdemsky  1.1.2.5  
1328 bdemsky  1.1.2.5              PHI phi=new PHI(qf,q,new Temp[0],2);
1329 bdemsky  1.1.2.5  
1330 bdemsky  1.1.2.5              Quad.addEdge(nc,0,phi,0);
1331 bdemsky  1.1.2.5              Quad.addEdge(nc,1,phi,1);
1332 bdemsky  1.1.2.1              addedCall.add(cq);
1333 bdemsky  1.1.2.5              quadmap.put(q, cq);
1334 bdemsky  1.1.2.1          } else
1335 bdemsky  1.1.2.5              quadmap.put(q, q.clone(qf, ctmap));
1336 bdemsky  1.1.2.5      }
1337 bdemsky  1.1.2.5  
1338 bdemsky  1.1.2.5      public boolean needsRepair() {
1339 bdemsky  1.1.2.5          return stillokay;
1340 bdemsky  1.1.2.2      }
1341 bdemsky  1.1.2.2  
1342 bdemsky  1.1.2.2      protected final static Temp[] map(TempMap tm, Temp[] ta) {
1343 bdemsky  1.1.2.2          Temp[] r = new Temp[ta.length];
1344 bdemsky  1.1.2.2          for (int i=0; i<r.length; i++)
1345 bdemsky  1.1.2.2              r[i] = tm.tempMap(ta[i]);
1346 bdemsky  1.1.2.2          return r;
1347 bdemsky  1.1.2.2      }
1348 bdemsky  1.1.2.2  
1349 bdemsky  1.1.2.2      protected final static Temp[][] map(TempMap tm, Temp[][] taa) {
1350 bdemsky  1.1.2.2          Temp[][] r = new Temp[taa.length][];
1351 bdemsky  1.1.2.2          for (int i=0; i<r.length; i++)
1352 bdemsky  1.1.2.2              r[i] = map(tm, taa[i]);
1353 bdemsky  1.1.2.2          return r;
1354 bdemsky  1.1.2.1      }
1355 bdemsky  1.1.2.1  
1356 bdemsky  1.1.2.1  
1357 bdemsky  1.1.2.1      /**
1358 bdemsky  1.1.2.1       * swapAdd takes in an <code>HMethod</code> and returns an <code>HMethod</code>
1359 bdemsky  1.1.2.1       * that is to be called following the first method is called.
1360 bdemsky  1.1.2.1       */
1361 bdemsky  1.1.2.1      public HMethod swapAdd(HMethod old) {
1362 bdemsky  1.1.2.1          HClass ss=linker.forName("java.net.ServerSocket");
1363 bdemsky  1.1.2.1          HClass fis=linker.forName("java.io.FileInputStream");
1364 bdemsky  1.1.2.9          HClass fos=linker.forName("java.io.FileOutputStream");
1365 bdemsky  1.1.2.1          if (old.equals(ss.getConstructor(new HClass[] {HClass.Int,
1366 bdemsky  1.1.2.1                                                             HClass.Int,
1367 bdemsky  1.1.2.1                                                             linker.forName("java.net.InetAddress")})))
1368 bdemsky  1.1.2.1              return ss.getDeclaredMethod("makeAsync", new HClass[0]);
1369 bdemsky  1.1.2.1          if (old.equals(fis.getConstructor(new HClass[] {linker.forName("java.lang.String")}))||
1370 bdemsky  1.1.2.1              old.equals(fis.getConstructor(new HClass[] {linker.forName("java.io.FileDescriptor")})))
1371 bdemsky  1.1.2.19             return fis.getMethod("makeAsync", new HClass[0]);
1372 bdemsky  1.1.2.20         if (old.equals(fos.getConstructor(new HClass[] {linker.forName("java.lang.String"), HClass.Boolean}))||
1373 bdemsky  1.1.2.20             old.equals(fos.getConstructor(new HClass[] {linker.forName("java.io.FileDescriptor")})))
1374 bdemsky  1.1.2.20             return fos.getMethod("makeAsync", new HClass[0]);
1375 bdemsky  1.1.2.1          return null;
1376 bdemsky  1.1.2.1      }
1377 bdemsky  1.1.2.1      
1378 bdemsky  1.1.2.1      /**
1379 bdemsky  1.1.2.1       * swapTo takes in an <code>HMethod</code> and returns an <code>HMethod</code>
1380 bdemsky  1.1.2.1       * that is to be called following the first method is called.
1381 bdemsky  1.1.2.1       */
1382 bdemsky  1.1.2.1      
1383 bdemsky  1.1.2.1      public HMethod swapTo(HMethod old) {
1384 bdemsky  1.1.2.1          //Handle Socket getInputStream calls
1385 bdemsky  1.1.2.1          HMethod gis=linker.forName("java.net.Socket")
1386 bdemsky  1.1.2.1              .getDeclaredMethod("getInputStream", new HClass[0]);
1387 bdemsky  1.1.2.1          if (gis.equals(old))
1388 bdemsky  1.1.2.1              return linker.forName("java.net.Socket").getDeclaredMethod
1389 bdemsky  1.1.2.1                  ("getAsyncInputStream", new HClass[0]);
1390 bdemsky  1.1.2.1          
1391 bdemsky  1.1.2.1  
1392 bdemsky  1.1.2.1          //Handle Socket getOutputStream calls
1393 bdemsky  1.1.2.1          HMethod  gos=linker.forName("java.net.Socket")
1394 bdemsky  1.1.2.1              .getDeclaredMethod("getOutputStream", new HClass[0]);
1395 bdemsky  1.1.2.1          if (gos.equals(old))
1396 bdemsky  1.1.2.1              return linker.forName("java.net.Socket").getDeclaredMethod
1397 bdemsky  1.1.2.1                  ("getAsyncOutputStream", new HClass[0]);
1398 bdemsky  1.1.2.1          
1399 bdemsky  1.1.2.1  
1400 bdemsky  1.1.2.1          //Handle start calls
1401 bdemsky  1.1.2.1          HClass HCthrd=linker.forName("java.lang.Thread");
1402 bdemsky  1.1.2.1          if (old.equals(HCthrd.getMethod("start",
1403 bdemsky  1.1.2.1                                          new HClass[0]))) {
1404 bdemsky  1.1.2.1              HMethod hmrun=old.getDeclaringClass().getMethod("run",
1405 bdemsky  1.1.2.1                                                              new HClass[0]);
1406 bdemsky  1.1.2.1              scheduleMethods(hmrun);
1407 bdemsky  1.1.2.1              return old.getDeclaringClass().getMethod("start_Async",
1408 bdemsky  1.1.2.1                                                       new HClass[0]);
1409 bdemsky  1.1.2.1          }
1410 bdemsky  1.1.2.1          
1411 bdemsky  1.1.2.1          //No match found
1412 bdemsky  1.1.2.1          return null;
1413 bdemsky  1.1.2.1      }
1414 cananian 1.2      }