more mlp code, needs dependency counts
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
1 package IR.Flat;
2 import IR.Tree.Modifiers;
3 import IR.Tree.FlagExpressionNode;
4 import IR.Tree.DNFFlag;
5 import IR.Tree.DNFFlagAtom;
6 import IR.Tree.TagExpressionList;
7 import IR.Tree.OffsetNode;
8 import IR.*;
9 import java.util.*;
10 import java.io.*;
11
12 import Util.Relation;
13 import Analysis.TaskStateAnalysis.FlagState;
14 import Analysis.TaskStateAnalysis.FlagComparator;
15 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
16 import Analysis.TaskStateAnalysis.Predicate;
17 import Analysis.TaskStateAnalysis.SafetyAnalysis;
18 import Analysis.TaskStateAnalysis.TaskIndex;
19 import Analysis.Locality.LocalityAnalysis;
20 import Analysis.Locality.LocalityBinding;
21 import Analysis.Locality.DiscoverConflicts;
22 import Analysis.CallGraph.CallGraph;
23 import Analysis.Prefetch.*;
24 import Analysis.Loops.WriteBarrier;
25 import Analysis.Locality.TypeAnalysis;
26 import Analysis.MLP.MLPAnalysis;
27
28 public class BuildCode {
29   State state;
30   Hashtable temptovar;
31   Hashtable paramstable;
32   Hashtable tempstable;
33   Hashtable fieldorder;
34   Hashtable flagorder;
35   int tag=0;
36   String localsprefix="___locals___";
37   String fcrevert="___fcrevert___";
38   String paramsprefix="___params___";
39   String oidstr="___nextobject___";
40   String nextobjstr="___nextobject___";
41   String localcopystr="___localcopy___";
42   public static boolean GENERATEPRECISEGC=false;
43   public static String PREFIX="";
44   public static String arraytype="ArrayObject";
45   public static int flagcount = 0;
46   Virtual virtualcalls;
47   TypeUtil typeutil;
48   protected int maxtaskparams=0;
49   private int maxcount=0;
50   ClassDescriptor[] cdarray;
51   TypeDescriptor[] arraytable;
52   LocalityAnalysis locality;
53   Hashtable<LocalityBinding, TempDescriptor> reverttable;
54   Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>> backuptable;
55   SafetyAnalysis sa;
56   PrefetchAnalysis pa;
57   MLPAnalysis mlpa;
58   String mlperrstr = "if(status != 0) { "+
59     "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
60     "perror(errmsg); exit(-1); }";
61   Hashtable<FlatSESEEnterNode, FlatMethod> sese2bogusFlatMeth;
62   boolean nonSESEpass=true;
63   WriteBarrier wb;
64   DiscoverConflicts dc;
65   CallGraph callgraph;
66
67   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) {
68     this(st, temptovar, typeutil, null, sa, pa, null);
69   }
70
71   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa, MLPAnalysis mlpa) {
72     this(st, temptovar, typeutil, null, sa, pa, mlpa);
73   }
74
75   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa, MLPAnalysis mlpa) {
76     this(st, temptovar, typeutil, locality, null, pa, mlpa);
77   }
78
79   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa, MLPAnalysis mlpa) {
80     this.sa=sa;
81     this.pa=pa;
82     this.mlpa=mlpa;
83     state=st;
84     callgraph=new CallGraph(state);
85     if (state.SINGLETM)
86       oidstr="___objlocation___";
87     this.temptovar=temptovar;
88     paramstable=new Hashtable();
89     tempstable=new Hashtable();
90     fieldorder=new Hashtable();
91     flagorder=new Hashtable();
92     this.typeutil=typeutil;
93     virtualcalls=new Virtual(state,locality);
94     if (locality!=null) {
95       this.locality=locality;
96       this.reverttable=new Hashtable<LocalityBinding, TempDescriptor>();
97       this.backuptable=new Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>>();
98       this.wb=new WriteBarrier(locality, st);
99     }
100     if (state.SINGLETM&&state.DCOPTS) {
101       TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
102       this.dc=new DiscoverConflicts(locality, st, typeanalysis);
103       dc.doAnalysis();
104     }
105     if(state.MLP) {
106       sese2bogusFlatMeth = new Hashtable<FlatSESEEnterNode, FlatMethod>();
107     }
108   }
109
110   /** The buildCode method outputs C code for all the methods.  The Flat
111    * versions of the methods must already be generated and stored in
112    * the State object. */
113
114   public void buildCode() {
115     /* Create output streams to write to */
116     PrintWriter outclassdefs=null;
117     PrintWriter outstructs=null;
118     PrintWriter outrepairstructs=null;
119     PrintWriter outmethodheader=null;
120     PrintWriter outmethod=null;
121     PrintWriter outvirtual=null;
122     PrintWriter outtask=null;
123     PrintWriter outtaskdefs=null;
124     PrintWriter outoptionalarrays=null;
125     PrintWriter optionalheaders=null;
126
127     try {
128       outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
129       outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
130       outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
131       outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
132       outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
133       if (state.TASK) {
134         outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
135         outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
136         if (state.OPTIONAL) {
137           outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
138           optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
139         }
140       }
141       if (state.structfile!=null) {
142         outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
143       }
144     } catch (Exception e) {
145       e.printStackTrace();
146       System.exit(-1);
147     }
148
149     /* Build the virtual dispatch tables */
150     buildVirtualTables(outvirtual);
151
152     /* Output includes */
153     outmethodheader.println("#ifndef METHODHEADERS_H");
154     outmethodheader.println("#define METHODHEADERS_H");
155     outmethodheader.println("#include \"structdefs.h\"");
156     if (state.DSM)
157       outmethodheader.println("#include \"dstm.h\"");
158     if (state.SINGLETM)
159       outmethodheader.println("#include \"tm.h\"");
160     if (state.ABORTREADERS) {
161       outmethodheader.println("#include \"abortreaders.h\"");
162       outmethodheader.println("#include <setjmp.h>");
163     }
164     if (state.MLP) {
165       outmethodheader.println("#include <stdlib.h>");
166       outmethodheader.println("#include <stdio.h>");
167       outmethodheader.println("#include \"mlp_runtime.h\"");
168     }
169
170     /* Output Structures */
171     outputStructs(outstructs);
172
173     // Output the C class declarations
174     // These could mutually reference each other
175     outputClassDeclarations(outclassdefs);
176
177     // Output function prototypes and structures for parameters
178     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
179     while(it.hasNext()) {
180       ClassDescriptor cn=(ClassDescriptor)it.next();
181       generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
182     }
183     outclassdefs.close();
184
185     if (state.TASK) {
186       /* Map flags to integers */
187       /* The runtime keeps track of flags using these integers */
188       it=state.getClassSymbolTable().getDescriptorsIterator();
189       while(it.hasNext()) {
190         ClassDescriptor cn=(ClassDescriptor)it.next();
191         mapFlags(cn);
192       }
193       /* Generate Tasks */
194       generateTaskStructs(outstructs, outmethodheader);
195
196       /* Outputs generic task structures if this is a task
197          program */
198       outputTaskTypes(outtask);
199     }
200
201     /* Build the actual methods */
202     outputMethods(outmethod);
203
204     // Output function prototypes and structures for SESE's and code
205     if( state.MLP ) {
206       nonSESEpass = false;
207
208       // first generate code for each sese's internals
209       for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
210         FlatSESEEnterNode fsen = seseit.next();
211         generateMethodSESE(fsen, null, outstructs, outmethodheader, outmethod);
212       }
213
214       // then write the invokeSESE switch to decouple scheduler
215       // from having to do unique details of sese invocation
216       generateSESEinvocationMethod(outmethodheader, outmethod);
217     }
218
219     if (state.TASK) {
220       /* Output code for tasks */
221       outputTaskCode(outtaskdefs, outmethod);
222       outtaskdefs.close();
223       /* Record maximum number of task parameters */
224       outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
225     } else if (state.main!=null) {
226       /* Generate main method */
227       outputMainMethod(outmethod);
228     }
229
230     /* Generate information for task with optional parameters */
231     if (state.TASK&&state.OPTIONAL) {
232       generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
233       outoptionalarrays.close();
234     }
235
236     /* Output structure definitions for repair tool */
237     if (state.structfile!=null) {
238       buildRepairStructs(outrepairstructs);
239       outrepairstructs.close();
240     }
241
242     /* Close files */
243     outmethodheader.println("#endif");
244     outmethodheader.close();
245     outmethod.close();
246     outstructs.println("#endif");
247     outstructs.close();
248   }
249
250
251   /* This code just generates the main C method for java programs.
252    * The main C method packs up the arguments into a string array
253    * and passes it to the java main method. */
254
255   private void outputMainMethod(PrintWriter outmethod) {
256     outmethod.println("int main(int argc, const char *argv[]) {");
257     outmethod.println("  int i;");
258     if (state.DSM) {
259       outmethod.println("#ifdef TRANSSTATS \n");
260       outmethod.println("handle();\n");
261       outmethod.println("#endif\n");
262     }
263     if (state.THREAD||state.DSM||state.SINGLETM) {
264       outmethod.println("initializethreads();");
265     }
266     if (state.DSM) {
267       outmethod.println("if (dstmStartup(argv[1])) {");
268       if (GENERATEPRECISEGC) {
269         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-2);");
270       } else {
271         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-2);");
272       }
273     } else {
274       if (GENERATEPRECISEGC) {
275         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
276       } else {
277         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
278       }
279     }
280     if (state.DSM) {
281       outmethod.println("  for(i=2;i<argc;i++) {");
282     } else
283       outmethod.println("  for(i=1;i<argc;i++) {");
284     outmethod.println("    int length=strlen(argv[i]);");
285     if (GENERATEPRECISEGC) {
286       outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
287     } else {
288       outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
289     }
290     if (state.DSM)
291       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-2]=newstring;");
292     else
293       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
294     outmethod.println("  }");
295
296     if (state.MLP) {
297       FlatSESEEnterNode rootSESE = mlpa.getRootSESE();
298       outmethod.println("  mlpInit();");
299
300       outmethod.print("  rootsese = mlpCreateSESErecord(");
301       outmethod.print(rootSESE.getIdentifier()+", 0, NULL, 0, NULL");
302       outmethod.println(");");
303
304       outmethod.println("  ");
305     }
306
307     MethodDescriptor md=typeutil.getMain();
308     ClassDescriptor cd=typeutil.getMainClass();
309
310     outmethod.println("   {");
311     if (GENERATEPRECISEGC) {
312       if (state.DSM||state.SINGLETM) {
313         outmethod.print("       struct "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
314       } else
315         outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
316       outmethod.println("1, NULL,"+"stringarray};");
317       if (state.DSM||state.SINGLETM)
318         outmethod.println("     "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
319       else
320         outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
321     } else {
322       if (state.DSM||state.SINGLETM)
323         outmethod.println("     "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
324       else
325         outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
326     }
327     outmethod.println("   }");
328
329     if (state.DSM) {
330       outmethod.println("}");
331     }
332
333     if (state.THREAD||state.DSM||state.SINGLETM) {
334       outmethod.println("pthread_mutex_lock(&gclistlock);");
335       outmethod.println("threadcount--;");
336       outmethod.println("pthread_cond_signal(&gccond);");
337       outmethod.println("pthread_mutex_unlock(&gclistlock);");
338     }
339
340     if (state.DSM||state.SINGLETM) {
341       outmethod.println("#ifdef TRANSSTATS \n");
342       outmethod.println("printf(\"******  Transaction Stats   ******\\n\");");
343       outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);");
344       outmethod.println("printf(\"numTransCommit= %d\\n\", numTransCommit);");
345       outmethod.println("printf(\"nSoftAbort= %d\\n\", nSoftAbort);");
346       if (state.DSM) {
347         outmethod.println("printf(\"nchashSearch= %d\\n\", nchashSearch);");
348         outmethod.println("printf(\"nmhashSearch= %d\\n\", nmhashSearch);");
349         outmethod.println("printf(\"nprehashSearch= %d\\n\", nprehashSearch);");
350         outmethod.println("printf(\"nRemoteReadSend= %d\\n\", nRemoteSend);");
351         outmethod.println("printf(\"bytesSent= %d\\n\", bytesSent);");
352         outmethod.println("printf(\"bytesRecv= %d\\n\", bytesRecv);");
353       } else if (state.SINGLETM) {
354         outmethod.println("printf(\"nSoftAbortAbort= %d\\n\", nSoftAbortAbort);");
355         outmethod.println("printf(\"nSoftAbortCommit= %d\\n\", nSoftAbortCommit);");
356         outmethod.println("#ifdef STMSTATS\n");
357         outmethod.println("for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {\n");
358         outmethod.println("  printf(\"typesCausingAbort[%d]= %d\\n\", i, typesCausingAbort[i]);\n");
359         outmethod.println("}\n");
360         outmethod.println("#endif\n");
361         outmethod.println("fflush(stdout);");
362       }
363       outmethod.println("#endif\n");
364     }
365
366     if (state.THREAD||state.SINGLETM)
367       outmethod.println("pthread_exit(NULL);");
368
369     outmethod.println("}");
370   }
371
372   /* This method outputs code for each task. */
373
374   private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
375     /* Compile task based program */
376     outtaskdefs.println("#include \"task.h\"");
377     outtaskdefs.println("#include \"methodheaders.h\"");
378     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
379     while(taskit.hasNext()) {
380       TaskDescriptor td=(TaskDescriptor)taskit.next();
381       FlatMethod fm=state.getMethodFlat(td);
382       generateFlatMethod(fm, null, outmethod);
383       generateTaskDescriptor(outtaskdefs, fm, td);
384     }
385
386     //Output task descriptors
387     taskit=state.getTaskSymbolTable().getDescriptorsIterator();
388     outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
389     boolean first=true;
390     while(taskit.hasNext()) {
391       TaskDescriptor td=(TaskDescriptor)taskit.next();
392       if (first)
393         first=false;
394       else
395         outtaskdefs.println(",");
396       outtaskdefs.print("&task_"+td.getSafeSymbol());
397     }
398     outtaskdefs.println("};");
399
400     outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
401   }
402
403   /* This method outputs most of the methods.c file.  This includes
404    * some standard includes and then an array with the sizes of
405    * objets and array that stores supertype and then the code for
406    * the Java methods.. */
407
408   protected void outputMethods(PrintWriter outmethod) {
409     outmethod.println("#include \"methodheaders.h\"");
410     outmethod.println("#include \"virtualtable.h\"");
411     outmethod.println("#include \"runtime.h\"");
412     if (state.DSM) {
413       outmethod.println("#include \"addPrefetchEnhance.h\"");
414       outmethod.println("#include \"localobjects.h\"");
415     }
416     if (state.FASTCHECK) {
417       outmethod.println("#include \"localobjects.h\"");
418     }
419     if(state.MULTICORE) {
420       outmethod.println("#include \"task.h\"");
421           outmethod.println("#include \"multicoreruntime.h\"");
422           outmethod.println("#include \"runtime_arch.h\"");
423     }
424     if (state.THREAD||state.DSM||state.SINGLETM)
425       outmethod.println("#include <thread.h>");
426     if (state.main!=null) {
427       outmethod.println("#include <string.h>");
428     }
429     if (state.CONSCHECK) {
430       outmethod.println("#include \"checkers.h\"");
431     }
432     if (state.MLP) {
433       outmethod.println("#include <stdlib.h>");
434       outmethod.println("#include <stdio.h>");
435       outmethod.println("#include \"mlp_runtime.h\"");
436       outmethod.println("/* GET RID OF THIS LATER */");
437       outmethod.println("SESErecord*     tempSESE;");
438       outmethod.println("SESErecord*     tempParentSESE;");    
439       outmethod.println("invokeSESEargs* tempSESEargs;");
440     }
441
442     //Store the sizes of classes & array elements
443     generateSizeArray(outmethod);
444
445     //Store table of supertypes
446     generateSuperTypeTable(outmethod);
447
448     //Store the layout of classes
449     generateLayoutStructs(outmethod);
450
451     /* Generate code for methods */
452     if (state.DSM||state.SINGLETM) {
453       for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator(); lbit.hasNext();) {
454         LocalityBinding lb=lbit.next();
455         MethodDescriptor md=lb.getMethod();
456         FlatMethod fm=state.getMethodFlat(md);
457         wb.analyze(lb);
458         if (!md.getModifiers().isNative()) {
459           generateFlatMethod(fm, lb, outmethod);
460         }
461       }
462     } else {
463       Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
464       while(classit.hasNext()) {
465         ClassDescriptor cn=(ClassDescriptor)classit.next();
466         Iterator methodit=cn.getMethods();
467         while(methodit.hasNext()) {
468           /* Classify parameters */
469           MethodDescriptor md=(MethodDescriptor)methodit.next();
470           FlatMethod fm=state.getMethodFlat(md);
471           if (!md.getModifiers().isNative()) {
472             generateFlatMethod(fm, null, outmethod);
473           }
474         }
475       }
476     }
477   }
478
479   protected void outputStructs(PrintWriter outstructs) {
480     outstructs.println("#ifndef STRUCTDEFS_H");
481     outstructs.println("#define STRUCTDEFS_H");
482     outstructs.println("#include \"classdefs.h\"");
483     outstructs.println("#ifndef INTPTR");
484     outstructs.println("#ifdef BIT64");
485     outstructs.println("#define INTPTR long");
486     outstructs.println("#else");
487     outstructs.println("#define INTPTR int");
488     outstructs.println("#endif");
489     outstructs.println("#endif");
490
491     /* Output #defines that the runtime uses to determine type
492      * numbers for various objects it needs */
493     outstructs.println("#define MAXCOUNT "+maxcount);
494     if (state.DSM||state.SINGLETM) {
495       LocalityBinding lb=new LocalityBinding(typeutil.getRun(), false);
496       if (state.DSM)
497         lb.setGlobalThis(LocalityAnalysis.GLOBAL);
498       else if (state.SINGLETM)
499         lb.setGlobalThis(LocalityAnalysis.NORMAL);
500       outstructs.println("#define RUNMETHOD "+virtualcalls.getLocalityNumber(lb));
501     }
502
503     outstructs.println("#define STRINGARRAYTYPE "+
504                        (state.getArrayNumber(
505                           (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
506
507     outstructs.println("#define OBJECTARRAYTYPE "+
508                        (state.getArrayNumber(
509                           (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
510
511
512     outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
513     outstructs.println("#define CHARARRAYTYPE "+
514                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
515
516     outstructs.println("#define BYTEARRAYTYPE "+
517                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
518
519     outstructs.println("#define BYTEARRAYARRAYTYPE "+
520                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
521
522     outstructs.println("#define NUMCLASSES "+state.numClasses());
523     int totalClassSize = state.numClasses() + state.numArrays();
524     outstructs.println("#define TOTALNUMCLASSANDARRAY "+ totalClassSize);
525     if (state.TASK) {
526       outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
527       outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
528       outstructs.println("#define TAGARRAYTYPE "+
529                          (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
530     }
531   }
532
533   protected void outputClassDeclarations(PrintWriter outclassdefs) {
534     if (state.THREAD||state.DSM||state.SINGLETM)
535       outclassdefs.println("#include <pthread.h>");
536     outclassdefs.println("#ifndef INTPTR");
537     outclassdefs.println("#ifdef BIT64");
538     outclassdefs.println("#define INTPTR long");
539     outclassdefs.println("#else");
540     outclassdefs.println("#define INTPTR int");
541     outclassdefs.println("#endif");
542     outclassdefs.println("#endif");
543     if(state.OPTIONAL)
544       outclassdefs.println("#include \"optionalstruct.h\"");
545     outclassdefs.println("struct "+arraytype+";");
546     /* Start by declaring all structs */
547     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
548     while(it.hasNext()) {
549       ClassDescriptor cn=(ClassDescriptor)it.next();
550       outclassdefs.println("struct "+cn.getSafeSymbol()+";");
551     }
552     outclassdefs.println("");
553     //Print out definition for array type
554     outclassdefs.println("struct "+arraytype+" {");
555     outclassdefs.println("  int type;");
556     if (state.THREAD) {
557       outclassdefs.println("  pthread_t tid;");
558       outclassdefs.println("  void * lockentry;");
559       outclassdefs.println("  int lockcount;");
560     }
561     if (state.TASK) {
562       outclassdefs.println("  int flag;");
563       if(!state.MULTICORE) {
564         outclassdefs.println("  void * flagptr;");
565       } else {
566         outclassdefs.println("  int isolate;");        // indicate if this object is shared or not
567         outclassdefs.println("  int version;");
568         outclassdefs.println("  struct ___Object___ * original;");
569         //outclassdefs.println("  int numlocks;");        // array for locks
570         outclassdefs.println("  int * lock;");
571       }
572       if(state.OPTIONAL) {
573         outclassdefs.println("  int numfses;");
574         outclassdefs.println("  int * fses;");
575       }
576     }
577     printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
578
579     outclassdefs.println("  int ___length___;");
580     outclassdefs.println("};\n");
581     outclassdefs.println("extern int classsize[];");
582     outclassdefs.println("extern int hasflags[];");
583     outclassdefs.println("extern unsigned INTPTR * pointerarray[];");
584     outclassdefs.println("extern int supertypes[];");
585   }
586
587   /** Prints out definitions for generic task structures */
588
589   private void outputTaskTypes(PrintWriter outtask) {
590     outtask.println("#ifndef _TASK_H");
591     outtask.println("#define _TASK_H");
592     outtask.println("struct parameterdescriptor {");
593     outtask.println("int type;");
594     outtask.println("int numberterms;");
595     outtask.println("int *intarray;");
596     outtask.println("void * queue;");
597     outtask.println("int numbertags;");
598     outtask.println("int *tagarray;");
599     outtask.println("};");
600
601     outtask.println("struct taskdescriptor {");
602     outtask.println("void * taskptr;");
603     outtask.println("int numParameters;");
604     outtask.println("  int numTotal;");
605     outtask.println("struct parameterdescriptor **descriptorarray;");
606     outtask.println("char * name;");
607     outtask.println("};");
608     outtask.println("extern struct taskdescriptor * taskarray[];");
609     outtask.println("extern numtasks;");
610     outtask.println("#endif");
611   }
612
613
614   private void buildRepairStructs(PrintWriter outrepairstructs) {
615     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
616     while(classit.hasNext()) {
617       ClassDescriptor cn=(ClassDescriptor)classit.next();
618       outrepairstructs.println("structure "+cn.getSymbol()+" {");
619       outrepairstructs.println("  int __type__;");
620       if (state.TASK) {
621         outrepairstructs.println("  int __flag__;");
622         if(!state.MULTICORE) {
623           outrepairstructs.println("  int __flagptr__;");
624         }
625       }
626       printRepairStruct(cn, outrepairstructs);
627       outrepairstructs.println("}\n");
628     }
629
630     for(int i=0; i<state.numArrays(); i++) {
631       TypeDescriptor tdarray=arraytable[i];
632       TypeDescriptor tdelement=tdarray.dereference();
633       outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
634       outrepairstructs.println("  int __type__;");
635       printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
636       outrepairstructs.println("  int length;");
637       /*
638          // Need to add support to repair tool for this
639          if (tdelement.isClass()||tdelement.isArray())
640           outrepairstructs.println("  "+tdelement.getRepairSymbol()+" * elem[this.length];");
641          else
642           outrepairstructs.println("  "+tdelement.getRepairSymbol()+" elem[this.length];");
643        */
644       outrepairstructs.println("}\n");
645     }
646   }
647
648   private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
649     ClassDescriptor sp=cn.getSuperDesc();
650     if (sp!=null)
651       printRepairStruct(sp, output);
652
653     Vector fields=(Vector)fieldorder.get(cn);
654
655     for(int i=0; i<fields.size(); i++) {
656       FieldDescriptor fd=(FieldDescriptor)fields.get(i);
657       if (fd.getType().isArray()) {
658         output.println("  "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
659       } else if (fd.getType().isClass())
660         output.println("  "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
661       else if (fd.getType().isFloat())
662         output.println("  int "+fd.getSymbol()+"; /* really float */");
663       else
664         output.println("  "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
665     }
666   }
667
668   /** This method outputs TaskDescriptor information */
669   private void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
670     for (int i=0; i<task.numParameters(); i++) {
671       VarDescriptor param_var=task.getParameter(i);
672       TypeDescriptor param_type=task.getParamType(i);
673       FlagExpressionNode param_flag=task.getFlag(param_var);
674       TagExpressionList param_tag=task.getTag(param_var);
675
676       int dnfterms;
677       if (param_flag==null) {
678         output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
679         output.println("0x0, 0x0 };");
680         dnfterms=1;
681       } else {
682         DNFFlag dflag=param_flag.getDNF();
683         dnfterms=dflag.size();
684
685         Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
686         output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
687         for(int j=0; j<dflag.size(); j++) {
688           if (j!=0)
689             output.println(",");
690           Vector term=dflag.get(j);
691           int andmask=0;
692           int checkmask=0;
693           for(int k=0; k<term.size(); k++) {
694             DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
695             FlagDescriptor fd=dfa.getFlag();
696             boolean negated=dfa.getNegated();
697             int flagid=1<<((Integer)flags.get(fd)).intValue();
698             andmask|=flagid;
699             if (!negated)
700               checkmask|=flagid;
701           }
702           output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
703         }
704         output.println("};");
705       }
706
707       output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
708       //BUG...added next line to fix, test with any task program
709       if (param_tag!=null)
710         for(int j=0; j<param_tag.numTags(); j++) {
711           if (j!=0)
712             output.println(",");
713           /* for each tag we need */
714           /* which slot it is */
715           /* what type it is */
716           TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
717           TempDescriptor tmp=param_tag.getTemp(j);
718           int slot=fm.getTagInt(tmp);
719           output.println(slot+", "+state.getTagId(tvd.getTag()));
720         }
721       output.println("};");
722
723       output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
724       output.println("/* type */"+param_type.getClassDesc().getId()+",");
725       output.println("/* number of DNF terms */"+dnfterms+",");
726       output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
727       output.println("0,");
728       //BUG, added next line to fix and else statement...test
729       //with any task program
730       if (param_tag!=null)
731         output.println("/* number of tags */"+param_tag.numTags()+",");
732       else
733         output.println("/* number of tags */ 0,");
734       output.println("parametertag_"+i+"_"+task.getSafeSymbol());
735       output.println("};");
736     }
737
738
739     output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
740     for (int i=0; i<task.numParameters(); i++) {
741       if (i!=0)
742         output.println(",");
743       output.print("&parameter_"+i+"_"+task.getSafeSymbol());
744     }
745     output.println("};");
746
747     output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
748     output.println("&"+task.getSafeSymbol()+",");
749     output.println("/* number of parameters */" +task.numParameters() + ",");
750     int numtotal=task.numParameters()+fm.numTags();
751     output.println("/* number total parameters */" +numtotal + ",");
752     output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
753     output.println("\""+task.getSymbol()+"\"");
754     output.println("};");
755   }
756
757
758   /** The buildVirtualTables method outputs the virtual dispatch
759    * tables for methods. */
760
761   protected void buildVirtualTables(PrintWriter outvirtual) {
762     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
763     while(classit.hasNext()) {
764       ClassDescriptor cd=(ClassDescriptor)classit.next();
765       if (virtualcalls.getMethodCount(cd)>maxcount)
766         maxcount=virtualcalls.getMethodCount(cd);
767     }
768     MethodDescriptor[][] virtualtable=null;
769     LocalityBinding[][] lbvirtualtable=null;
770     if (state.DSM||state.SINGLETM)
771       lbvirtualtable=new LocalityBinding[state.numClasses()+state.numArrays()][maxcount];
772     else
773       virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
774
775     /* Fill in virtual table */
776     classit=state.getClassSymbolTable().getDescriptorsIterator();
777     while(classit.hasNext()) {
778       ClassDescriptor cd=(ClassDescriptor)classit.next();
779       if (state.DSM||state.SINGLETM)
780         fillinRow(cd, lbvirtualtable, cd.getId());
781       else
782         fillinRow(cd, virtualtable, cd.getId());
783     }
784
785     ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
786     Iterator arrayit=state.getArrayIterator();
787     while(arrayit.hasNext()) {
788       TypeDescriptor td=(TypeDescriptor)arrayit.next();
789       int id=state.getArrayNumber(td);
790       if (state.DSM||state.SINGLETM)
791         fillinRow(objectcd, lbvirtualtable, id+state.numClasses());
792       else
793         fillinRow(objectcd, virtualtable, id+state.numClasses());
794     }
795
796     outvirtual.print("void * virtualtable[]={");
797     boolean needcomma=false;
798     for(int i=0; i<state.numClasses()+state.numArrays(); i++) {
799       for(int j=0; j<maxcount; j++) {
800         if (needcomma)
801           outvirtual.print(", ");
802         if ((state.DSM||state.SINGLETM)&&lbvirtualtable[i][j]!=null) {
803           LocalityBinding lb=lbvirtualtable[i][j];
804           MethodDescriptor md=lb.getMethod();
805           outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
806         } else if (!(state.DSM||state.SINGLETM)&&virtualtable[i][j]!=null) {
807           MethodDescriptor md=virtualtable[i][j];
808           outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
809         } else {
810           outvirtual.print("0");
811         }
812         needcomma=true;
813       }
814       outvirtual.println("");
815     }
816     outvirtual.println("};");
817     outvirtual.close();
818   }
819
820   private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
821     /* Get inherited methods */
822     if (cd.getSuperDesc()!=null)
823       fillinRow(cd.getSuperDesc(), virtualtable, rownum);
824     /* Override them with our methods */
825     for(Iterator it=cd.getMethods(); it.hasNext();) {
826       MethodDescriptor md=(MethodDescriptor)it.next();
827       if (md.isStatic()||md.getReturnType()==null)
828         continue;
829       int methodnum=virtualcalls.getMethodNumber(md);
830       virtualtable[rownum][methodnum]=md;
831     }
832   }
833
834   private void fillinRow(ClassDescriptor cd, LocalityBinding[][] virtualtable, int rownum) {
835     /* Get inherited methods */
836     if (cd.getSuperDesc()!=null)
837       fillinRow(cd.getSuperDesc(), virtualtable, rownum);
838     /* Override them with our methods */
839     if (locality.getClassBindings(cd)!=null)
840       for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cd).iterator(); lbit.hasNext();) {
841         LocalityBinding lb=lbit.next();
842         MethodDescriptor md=lb.getMethod();
843         //Is the method static or a constructor
844         if (md.isStatic()||md.getReturnType()==null)
845           continue;
846         int methodnum=virtualcalls.getLocalityNumber(lb);
847         virtualtable[rownum][methodnum]=lb;
848       }
849   }
850
851   /** Generate array that contains the sizes of class objects.  The
852    * object allocation functions in the runtime use this
853    * information. */
854
855   private void generateSizeArray(PrintWriter outclassdefs) {
856     outclassdefs.print("extern struct prefetchCountStats * evalPrefetch;\n");
857     outclassdefs.print("#ifdef TRANSSTATS \n");
858     outclassdefs.print("extern int numTransAbort;\n");
859     outclassdefs.print("extern int numTransCommit;\n");
860     outclassdefs.print("extern int nSoftAbort;\n");
861     if (state.DSM) {
862       outclassdefs.print("extern int nchashSearch;\n");
863       outclassdefs.print("extern int nmhashSearch;\n");
864       outclassdefs.print("extern int nprehashSearch;\n");
865       outclassdefs.print("extern int nRemoteSend;\n");
866       outclassdefs.print("extern int bytesSent;\n");
867       outclassdefs.print("extern int bytesRecv;\n");
868       outclassdefs.print("extern void handle();\n");
869     } else if (state.SINGLETM) {
870       outclassdefs.println("extern int nSoftAbortAbort;");
871       outclassdefs.println("extern int nSoftAbortCommit;");
872       outclassdefs.println("#ifdef STMSTATS\n");
873       outclassdefs.println("extern int typesCausingAbort[];");
874       outclassdefs.println("#endif\n");
875     }
876     outclassdefs.print("#endif\n");
877     outclassdefs.print("int numprefetchsites = " + pa.prefetchsiteid + ";\n");
878
879     outclassdefs.print("int classsize[]={");
880     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
881     cdarray=new ClassDescriptor[state.numClasses()];
882     while(it.hasNext()) {
883       ClassDescriptor cd=(ClassDescriptor)it.next();
884       cdarray[cd.getId()]=cd;
885     }
886     boolean needcomma=false;
887     for(int i=0; i<state.numClasses(); i++) {
888       if (needcomma)
889         outclassdefs.print(", ");
890       outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
891       needcomma=true;
892     }
893
894
895     arraytable=new TypeDescriptor[state.numArrays()];
896
897     Iterator arrayit=state.getArrayIterator();
898     while(arrayit.hasNext()) {
899       TypeDescriptor td=(TypeDescriptor)arrayit.next();
900       int id=state.getArrayNumber(td);
901       arraytable[id]=td;
902     }
903
904     for(int i=0; i<state.numArrays(); i++) {
905       if (needcomma)
906         outclassdefs.print(", ");
907       TypeDescriptor tdelement=arraytable[i].dereference();
908       if (tdelement.isArray()||tdelement.isClass())
909         outclassdefs.print("sizeof(void *)");
910       else
911         outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
912       needcomma=true;
913     }
914
915     outclassdefs.println("};");
916
917     ClassDescriptor objectclass=typeutil.getClass(TypeUtil.ObjectClass);
918     needcomma=false;
919     outclassdefs.print("int typearray[]={");
920     for(int i=0; i<state.numClasses(); i++) {
921       ClassDescriptor cd=cdarray[i];
922       ClassDescriptor supercd=cd.getSuperDesc();
923       if (needcomma)
924         outclassdefs.print(", ");
925       if (supercd==null)
926         outclassdefs.print("-1");
927       else
928         outclassdefs.print(supercd.getId());
929       needcomma=true;
930     }
931
932     for(int i=0; i<state.numArrays(); i++) {
933       TypeDescriptor arraytd=arraytable[i];
934       ClassDescriptor arraycd=arraytd.getClassDesc();
935       if (arraycd==null) {
936         if (needcomma)
937           outclassdefs.print(", ");
938         outclassdefs.print(objectclass.getId());
939         needcomma=true;
940         continue;
941       }
942       ClassDescriptor cd=arraycd.getSuperDesc();
943       int type=-1;
944       while(cd!=null) {
945         TypeDescriptor supertd=new TypeDescriptor(cd);
946         supertd.setArrayCount(arraytd.getArrayCount());
947         type=state.getArrayNumber(supertd);
948         if (type!=-1) {
949           type+=state.numClasses();
950           break;
951         }
952         cd=cd.getSuperDesc();
953       }
954       if (needcomma)
955         outclassdefs.print(", ");
956       outclassdefs.print(type);
957       needcomma=true;
958     }
959
960     outclassdefs.println("};");
961
962     needcomma=false;
963
964
965     outclassdefs.print("int typearray2[]={");
966     for(int i=0; i<state.numArrays(); i++) {
967       TypeDescriptor arraytd=arraytable[i];
968       ClassDescriptor arraycd=arraytd.getClassDesc();
969       if (arraycd==null) {
970         if (needcomma)
971           outclassdefs.print(", ");
972         outclassdefs.print("-1");
973         needcomma=true;
974         continue;
975       }
976       ClassDescriptor cd=arraycd.getSuperDesc();
977       int level=arraytd.getArrayCount()-1;
978       int type=-1;
979       for(; level>0; level--) {
980         TypeDescriptor supertd=new TypeDescriptor(objectclass);
981         supertd.setArrayCount(level);
982         type=state.getArrayNumber(supertd);
983         if (type!=-1) {
984           type+=state.numClasses();
985           break;
986         }
987       }
988       if (needcomma)
989         outclassdefs.print(", ");
990       outclassdefs.print(type);
991       needcomma=true;
992     }
993
994     outclassdefs.println("};");
995   }
996
997   /** Constructs params and temp objects for each method or task.
998    * These objects tell the compiler which temps need to be
999    * allocated.  */
1000
1001   protected void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
1002     MethodDescriptor md=fm.getMethod();
1003     TaskDescriptor task=fm.getTask();
1004     Set<TempDescriptor> saveset=lb!=null ? locality.getTempSet(lb) : null;
1005     ParamsObject objectparams=md!=null ? new ParamsObject(md,tag++) : new ParamsObject(task, tag++);
1006     if (lb!=null) {
1007       paramstable.put(lb, objectparams);
1008       backuptable.put(lb, new Hashtable<TempDescriptor, TempDescriptor>());
1009     } else if (md!=null)
1010       paramstable.put(md, objectparams);
1011     else
1012       paramstable.put(task, objectparams);
1013
1014     for(int i=0; i<fm.numParameters(); i++) {
1015       TempDescriptor temp=fm.getParameter(i);
1016       TypeDescriptor type=temp.getType();
1017       if (type.isPtr()&&GENERATEPRECISEGC)
1018         objectparams.addPtr(temp);
1019       else
1020         objectparams.addPrim(temp);
1021       if(lb!=null&&saveset.contains(temp)) {
1022         backuptable.get(lb).put(temp, temp.createNew());
1023       }
1024     }
1025
1026     for(int i=0; i<fm.numTags(); i++) {
1027       TempDescriptor temp=fm.getTag(i);
1028       if (GENERATEPRECISEGC)
1029         objectparams.addPtr(temp);
1030       else
1031         objectparams.addPrim(temp);
1032     }
1033
1034     TempObject objecttemps=md!=null ? new TempObject(objectparams,md,tag++) : new TempObject(objectparams, task, tag++);
1035     if (lb!=null)
1036       tempstable.put(lb, objecttemps);
1037     else if (md!=null)
1038       tempstable.put(md, objecttemps);
1039     else
1040       tempstable.put(task, objecttemps);
1041
1042     for(Iterator nodeit=fm.getNodeSet().iterator(); nodeit.hasNext();) {
1043       FlatNode fn=(FlatNode)nodeit.next();
1044       TempDescriptor[] writes=fn.writesTemps();
1045       for(int i=0; i<writes.length; i++) {
1046         TempDescriptor temp=writes[i];
1047         TypeDescriptor type=temp.getType();
1048         if (type.isPtr()&&GENERATEPRECISEGC)
1049           objecttemps.addPtr(temp);
1050         else
1051           objecttemps.addPrim(temp);
1052         if(lb!=null&&saveset.contains(temp)&&
1053            !backuptable.get(lb).containsKey(temp))
1054           backuptable.get(lb).put(temp, temp.createNew());
1055       }
1056     }
1057
1058     /* Create backup temps */
1059     if (lb!=null) {
1060       for(Iterator<TempDescriptor> tmpit=backuptable.get(lb).values().iterator(); tmpit.hasNext();) {
1061         TempDescriptor tmp=tmpit.next();
1062         TypeDescriptor type=tmp.getType();
1063         if (type.isPtr()&&GENERATEPRECISEGC)
1064           objecttemps.addPtr(tmp);
1065         else
1066           objecttemps.addPrim(tmp);
1067       }
1068       /* Create temp to hold revert table */
1069       if (state.DSM&&(lb.getHasAtomic()||lb.isAtomic())) {
1070         TempDescriptor reverttmp=new TempDescriptor("revertlist", typeutil.getClass(TypeUtil.ObjectClass));
1071         if (GENERATEPRECISEGC)
1072           objecttemps.addPtr(reverttmp);
1073         else
1074           objecttemps.addPrim(reverttmp);
1075         reverttable.put(lb, reverttmp);
1076       }
1077     }
1078   }
1079
1080   /** This method outputs the following information about classes
1081    * and arrays:
1082    * (1) For classes, what are the locations of pointers.
1083    * (2) For arrays, does the array contain pointers or primitives.
1084    * (3) For classes, does the class contain flags.
1085    */
1086
1087   private void generateLayoutStructs(PrintWriter output) {
1088     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
1089     while(it.hasNext()) {
1090       ClassDescriptor cn=(ClassDescriptor)it.next();
1091       output.println("unsigned INTPTR "+cn.getSafeSymbol()+"_pointers[]={");
1092       Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
1093       int count=0;
1094       while(allit.hasNext()) {
1095         FieldDescriptor fd=(FieldDescriptor)allit.next();
1096         TypeDescriptor type=fd.getType();
1097         if (state.DSM&&fd.isGlobal())         //Don't GC the global objects for now
1098           continue;
1099         if (type.isPtr())
1100           count++;
1101       }
1102       output.print(count);
1103       allit=cn.getFieldTable().getAllDescriptorsIterator();
1104       while(allit.hasNext()) {
1105         FieldDescriptor fd=(FieldDescriptor)allit.next();
1106         TypeDescriptor type=fd.getType();
1107         if (state.DSM&&fd.isGlobal())         //Don't GC the global objects for now
1108           continue;
1109         if (type.isPtr()) {
1110           output.println(",");
1111           output.print("((unsigned INTPTR)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
1112         }
1113       }
1114       output.println("};");
1115     }
1116     output.println("unsigned INTPTR * pointerarray[]={");
1117     boolean needcomma=false;
1118     for(int i=0; i<state.numClasses(); i++) {
1119       ClassDescriptor cn=cdarray[i];
1120       if (needcomma)
1121         output.println(",");
1122       needcomma=true;
1123       output.print(cn.getSafeSymbol()+"_pointers");
1124     }
1125
1126     for(int i=0; i<state.numArrays(); i++) {
1127       if (needcomma)
1128         output.println(", ");
1129       TypeDescriptor tdelement=arraytable[i].dereference();
1130       if (tdelement.isArray()||tdelement.isClass())
1131         output.print("((unsigned INTPTR *)1)");
1132       else
1133         output.print("0");
1134       needcomma=true;
1135     }
1136
1137     output.println("};");
1138     needcomma=false;
1139     output.println("int hasflags[]={");
1140     for(int i=0; i<state.numClasses(); i++) {
1141       ClassDescriptor cn=cdarray[i];
1142       if (needcomma)
1143         output.println(", ");
1144       needcomma=true;
1145       if (cn.hasFlags())
1146         output.print("1");
1147       else
1148         output.print("0");
1149     }
1150     output.println("};");
1151   }
1152
1153   /** Print out table to give us supertypes */
1154   private void generateSuperTypeTable(PrintWriter output) {
1155     output.println("int supertypes[]={");
1156     boolean needcomma=false;
1157     for(int i=0; i<state.numClasses(); i++) {
1158       ClassDescriptor cn=cdarray[i];
1159       if (needcomma)
1160         output.println(",");
1161       needcomma=true;
1162       if (cn.getSuperDesc()!=null) {
1163         ClassDescriptor cdsuper=cn.getSuperDesc();
1164         output.print(cdsuper.getId());
1165       } else
1166         output.print("-1");
1167     }
1168     output.println("};");
1169   }
1170
1171   /** Force consistent field ordering between inherited classes. */
1172
1173   private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
1174
1175     ClassDescriptor sp=cn.getSuperDesc();
1176     if (sp!=null)
1177       printClassStruct(sp, classdefout);
1178
1179     if (!fieldorder.containsKey(cn)) {
1180       Vector fields=new Vector();
1181       fieldorder.put(cn,fields);
1182       if (sp==null&&!state.TASK) {
1183         fields.add(cn.getFieldTable().get("cachedCode"));
1184       }
1185       Iterator fieldit=cn.getFields();
1186       while(fieldit.hasNext()) {
1187         FieldDescriptor fd=(FieldDescriptor)fieldit.next();
1188         if ((sp==null||!sp.getFieldTable().contains(fd.getSymbol()))&&
1189             (!fd.getSymbol().equals("cachedCode")||state.TASK))
1190           fields.add(fd);
1191       }
1192     }
1193     Vector fields=(Vector)fieldorder.get(cn);
1194
1195     for(int i=0; i<fields.size(); i++) {
1196       FieldDescriptor fd=(FieldDescriptor)fields.get(i);
1197       if (fd.getType().isClass()||fd.getType().isArray())
1198         classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
1199       else
1200         classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
1201     }
1202   }
1203
1204
1205   /* Map flags to integers consistently between inherited
1206    * classes. */
1207
1208   protected void mapFlags(ClassDescriptor cn) {
1209     ClassDescriptor sp=cn.getSuperDesc();
1210     if (sp!=null)
1211       mapFlags(sp);
1212     int max=0;
1213     if (!flagorder.containsKey(cn)) {
1214       Hashtable flags=new Hashtable();
1215       flagorder.put(cn,flags);
1216       if (sp!=null) {
1217         Hashtable superflags=(Hashtable)flagorder.get(sp);
1218         Iterator superflagit=superflags.keySet().iterator();
1219         while(superflagit.hasNext()) {
1220           FlagDescriptor fd=(FlagDescriptor)superflagit.next();
1221           Integer number=(Integer)superflags.get(fd);
1222           flags.put(fd, number);
1223           if ((number.intValue()+1)>max)
1224             max=number.intValue()+1;
1225         }
1226       }
1227
1228       Iterator flagit=cn.getFlags();
1229       while(flagit.hasNext()) {
1230         FlagDescriptor fd=(FlagDescriptor)flagit.next();
1231         if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
1232           flags.put(fd, new Integer(max++));
1233       }
1234     }
1235   }
1236
1237
1238   /** This function outputs (1) structures that parameters are
1239    * passed in (when PRECISE GC is enabled) and (2) function
1240    * prototypes for the methods */
1241
1242   protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
1243     /* Output class structure */
1244     classdefout.println("struct "+cn.getSafeSymbol()+" {");
1245     classdefout.println("  int type;");
1246     if (state.THREAD) {
1247       classdefout.println("  pthread_t tid;");
1248       classdefout.println("  void * lockentry;");
1249       classdefout.println("  int lockcount;");
1250     }
1251
1252     if (state.TASK) {
1253       classdefout.println("  int flag;");
1254       if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
1255         classdefout.println("  void * flagptr;");
1256       } else if (state.MULTICORE) {
1257         classdefout.println("  int isolate;");        // indicate if this object is shared or not
1258         classdefout.println("  int version;");
1259         classdefout.println("  struct ___Object___ * original;");
1260         //classdefout.println("  int numlocks;");        // array for locks
1261         classdefout.println("  int * lock;");
1262       }
1263       if (state.OPTIONAL) {
1264         classdefout.println("  int numfses;");
1265         classdefout.println("  int * fses;");
1266       }
1267     }
1268     printClassStruct(cn, classdefout);
1269     classdefout.println("};\n");
1270
1271     if (state.DSM||state.SINGLETM) {
1272       /* Cycle through LocalityBindings */
1273       HashSet<MethodDescriptor> nativemethods=new HashSet<MethodDescriptor>();
1274       Set<LocalityBinding> lbset=locality.getClassBindings(cn);
1275       if (lbset!=null) {
1276         for(Iterator<LocalityBinding> lbit=lbset.iterator(); lbit.hasNext();) {
1277           LocalityBinding lb=lbit.next();
1278           MethodDescriptor md=lb.getMethod();
1279           if (md.getModifiers().isNative()) {
1280             //make sure we only print a native method once
1281             if (nativemethods.contains(md)) {
1282               FlatMethod fm=state.getMethodFlat(md);
1283               generateTempStructs(fm, lb);
1284               continue;
1285             } else
1286               nativemethods.add(md);
1287           }
1288           generateMethod(cn, md, lb, headersout, output);
1289         }
1290       }
1291       for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1292         MethodDescriptor md=(MethodDescriptor)methodit.next();
1293         if (md.getModifiers().isNative()&&!nativemethods.contains(md)) {
1294           //Need to build param structure for library code
1295           FlatMethod fm=state.getMethodFlat(md);
1296           generateTempStructs(fm, null);
1297           generateMethodParam(cn, md, null, output);
1298         }
1299       }
1300
1301     } else
1302       for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1303         MethodDescriptor md=(MethodDescriptor)methodit.next();
1304         generateMethod(cn, md, null, headersout, output);
1305       }
1306   }
1307
1308   private void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter output) {
1309     /* Output parameter structure */
1310     if (GENERATEPRECISEGC) {
1311       ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1312       if ((state.DSM||state.SINGLETM)&&lb!=null)
1313         output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1314       else
1315         output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1316       output.println("  INTPTR size;");
1317       output.println("  void * next;");
1318       for(int i=0; i<objectparams.numPointers(); i++) {
1319         TempDescriptor temp=objectparams.getPointer(i);
1320         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1321       }
1322       output.println("};\n");
1323     }
1324   }
1325
1326
1327   private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
1328     FlatMethod fm=state.getMethodFlat(md);
1329     generateTempStructs(fm, lb);
1330
1331     ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1332     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md);
1333
1334     generateMethodParam(cn, md, lb, output);
1335
1336     /* Output temp structure */
1337     if (GENERATEPRECISEGC) {
1338       if (state.DSM||state.SINGLETM)
1339         output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1340       else
1341         output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1342       output.println("  INTPTR size;");
1343       output.println("  void * next;");
1344       for(int i=0; i<objecttemps.numPointers(); i++) {
1345         TempDescriptor temp=objecttemps.getPointer(i);
1346         if (temp.getType().isNull())
1347           output.println("  void * "+temp.getSafeSymbol()+";");
1348         else
1349           output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1350       }
1351       output.println("};\n");
1352     }
1353
1354     /********* Output method declaration ***********/
1355     if (state.DSM||state.SINGLETM) {
1356       headersout.println("#define D"+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1357     } else {
1358       headersout.println("#define D"+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1359     }
1360     /* First the return type */
1361     if (md.getReturnType()!=null) {
1362       if (md.getReturnType().isClass()||md.getReturnType().isArray())
1363         headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1364       else
1365         headersout.print(md.getReturnType().getSafeSymbol()+" ");
1366     } else
1367       //catch the constructor case
1368       headersout.print("void ");
1369
1370     /* Next the method name */
1371     if (state.DSM||state.SINGLETM) {
1372       headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1373     } else {
1374       headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1375     }
1376     boolean printcomma=false;
1377     if (GENERATEPRECISEGC) {
1378       if (state.DSM||state.SINGLETM) {
1379         headersout.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1380       } else
1381         headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1382       printcomma=true;
1383     }
1384
1385     /*  Output parameter list*/
1386     for(int i=0; i<objectparams.numPrimitives(); i++) {
1387       TempDescriptor temp=objectparams.getPrimitive(i);
1388       if (printcomma)
1389         headersout.print(", ");
1390       printcomma=true;
1391       if (temp.getType().isClass()||temp.getType().isArray())
1392         headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1393       else
1394         headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1395     }
1396     headersout.println(");\n");
1397   }
1398
1399
1400   /** This function outputs (1) structures that parameters are
1401    * passed in (when PRECISE GC is enabled) and (2) function
1402    * prototypes for the tasks */
1403
1404   private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
1405     /* Cycle through tasks */
1406     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1407
1408     while(taskit.hasNext()) {
1409       /* Classify parameters */
1410       TaskDescriptor task=(TaskDescriptor)taskit.next();
1411       FlatMethod fm=state.getMethodFlat(task);
1412       generateTempStructs(fm, null);
1413
1414       ParamsObject objectparams=(ParamsObject) paramstable.get(task);
1415       TempObject objecttemps=(TempObject) tempstable.get(task);
1416
1417       /* Output parameter structure */
1418       if (GENERATEPRECISEGC) {
1419         output.println("struct "+task.getSafeSymbol()+"_params {");
1420
1421         output.println("  INTPTR size;");
1422         output.println("  void * next;");
1423         for(int i=0; i<objectparams.numPointers(); i++) {
1424           TempDescriptor temp=objectparams.getPointer(i);
1425           output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1426         }
1427
1428         output.println("};\n");
1429         if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1430           maxtaskparams=objectparams.numPointers()+fm.numTags();
1431         }
1432       }
1433
1434       /* Output temp structure */
1435       if (GENERATEPRECISEGC) {
1436         output.println("struct "+task.getSafeSymbol()+"_locals {");
1437         output.println("  INTPTR size;");
1438         output.println("  void * next;");
1439         for(int i=0; i<objecttemps.numPointers(); i++) {
1440           TempDescriptor temp=objecttemps.getPointer(i);
1441           if (temp.getType().isNull())
1442             output.println("  void * "+temp.getSafeSymbol()+";");
1443           else if(temp.getType().isTag())
1444             output.println("  struct "+
1445                            (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1446           else
1447             output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1448         }
1449         output.println("};\n");
1450       }
1451
1452       /* Output task declaration */
1453       headersout.print("void " + task.getSafeSymbol()+"(");
1454
1455       boolean printcomma=false;
1456       if (GENERATEPRECISEGC) {
1457         headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1458       } else
1459         headersout.print("void * parameterarray[]");
1460       headersout.println(");\n");
1461     }
1462   }
1463
1464   /***** Generate code for FlatMethod fm. *****/
1465
1466   private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1467     if (State.PRINTFLAT)
1468       System.out.println(fm.printMethod());
1469     MethodDescriptor md=fm.getMethod();
1470
1471     TaskDescriptor task=fm.getTask();
1472
1473     ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
1474
1475     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : md!=null ? md : task);
1476     generateHeader(fm, lb, md!=null ? md : task,output);
1477     TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1478
1479     if (GENERATEPRECISEGC) {
1480       if (md!=null&&(state.DSM||state.SINGLETM))
1481         output.print("   struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1482       else if (md!=null&&!(state.DSM||state.SINGLETM))
1483         output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1484       else
1485         output.print("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1486
1487       output.print(objecttemp.numPointers()+",");
1488       output.print(paramsprefix);
1489       for(int j=0; j<objecttemp.numPointers(); j++)
1490         output.print(", NULL");
1491       output.println("};");
1492     }
1493
1494     for(int i=0; i<objecttemp.numPrimitives(); i++) {
1495       TempDescriptor td=objecttemp.getPrimitive(i);
1496       TypeDescriptor type=td.getType();
1497       if (type.isNull())
1498         output.println("   void * "+td.getSafeSymbol()+";");
1499       else if (type.isClass()||type.isArray())
1500         output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1501       else
1502         output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1503     }
1504
1505     /* Check to see if we need to do a GC if this is a
1506      * multi-threaded program...*/
1507
1508     if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
1509       //Don't bother if we aren't in recursive methods...The loops case will catch it
1510       if (callgraph.getAllMethods(md).contains(md)) {
1511         if (state.DSM&&lb.isAtomic())
1512           output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
1513         else
1514           output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
1515       }
1516     }
1517
1518     generateCode(fm.getNext(0), fm, lb, null, output);
1519
1520     output.println("}\n\n");
1521   }
1522
1523   // when a new mlp thread is created for an issued SESE, it is started
1524   // by running this method which blocks on a cond variable until
1525   // it is allowed to transition to execute.  Then a case statement
1526   // allows it to invoke the method with the proper SESE body, and after
1527   // exiting the SESE method, executes proper SESE exit code before the
1528   // thread can be destroyed
1529   private void generateSESEinvocationMethod(PrintWriter outmethodheader,
1530                                             PrintWriter outmethod
1531                                             ) {
1532
1533     outmethodheader.println("void* invokeSESEmethod( void* vargs );");
1534     outmethod.println(      "void* invokeSESEmethod( void* vargs ) {");
1535     outmethod.println(      "  int status;");
1536     outmethod.println(      "  char errmsg[128];");
1537     outmethod.println(      "  invokeSESEargs* args = (invokeSESEargs*) vargs;");
1538
1539     // wait on a condition variable that dispatcher will signal
1540     // then this SESE instance's dependencies are resolved
1541     outmethod.println(      "  status = pthread_mutex_lock( args->invokee->startCondVarLock );");
1542     outmethod.println(      "  "+mlperrstr);
1543     outmethod.println(      "  while( !(args->invokee->startedExecuting) ){");
1544     outmethod.println(      "    status = pthread_cond_wait( args->invokee->startCondVar, args->invokee->startCondVarLock );");
1545     outmethod.println(      "    "+mlperrstr);
1546     outmethod.println(      "  }");
1547
1548     // generate a case for each SESE class that can be invoked
1549     outmethod.println(      "  switch( args->classID ) {");
1550     outmethod.println(      "    ");
1551     for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
1552       FlatSESEEnterNode fsen = seseit.next();
1553       outmethod.println(    "    /* "+fsen.getPrettyIdentifier()+" */");
1554       outmethod.println(    "    case "+fsen.getIdentifier()+":");
1555       generateSESEinvocation(fsen, outmethod);
1556       outmethod.println(    "      break;");
1557       outmethod.println(    "");
1558     }
1559
1560     // default case should never be taken, error out
1561     outmethod.println(      "    default:");
1562     outmethod.println(      "      printf(\"Error: unknown SESE class ID in invoke method.\\n\");");
1563     outmethod.println(      "      exit(-30);");
1564     outmethod.println(      "      break;");
1565     outmethod.println(      "  }");
1566     outmethod.println(      "}\n\n");
1567   }
1568
1569   private void generateSESEinvocation(FlatSESEEnterNode fsen,
1570                                       PrintWriter output
1571                                       ) {
1572
1573     FlatMethod       fm = fsen.getEnclosingFlatMeth();
1574     MethodDescriptor md = fm.getMethod();
1575     ClassDescriptor  cn = md.getClassDesc();
1576
1577     FlatMethod       bogusfm  = sese2bogusFlatMeth.get(fsen);
1578     MethodDescriptor bogusmd  = bogusfm.getMethod();
1579     ParamsObject objectparams = (ParamsObject)paramstable.get(bogusmd);
1580
1581     // first copy SESE record into param structure
1582
1583
1584     // then invoke the sese's method
1585     output.print("      "+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"_"+bogusmd.getSafeMethodDescriptor());
1586     output.print("(");
1587
1588     // why doesn't this work?
1589     //output.print("("+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"_"+bogusmd.getSafeMethodDescriptor()+paramsprefix+")");
1590
1591     // first argument is parameter structure
1592     output.print("(struct "+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"__params*)");
1593     output.print("&(args->invokee->paramStruct)");
1594
1595     // other arguments are primitive parameters
1596     for(int i=0; i<objectparams.numPrimitives(); i++) {
1597       TempDescriptor td=objectparams.getPrimitive(i);
1598       TypeDescriptor type=td.getType();
1599       assert type.isPrimitive();
1600       output.print(", args->invokee->vars["+i+"].sesetype_"+type.toString());
1601     }
1602     
1603     output.println(");");
1604   }
1605
1606   private void generateFlatMethodSESE(FlatMethod fm, 
1607                                       ClassDescriptor cn, 
1608                                       FlatSESEEnterNode seseEnter, 
1609                                       FlatSESEExitNode  seseExit, 
1610                                       PrintWriter output
1611                                       ) {
1612
1613     MethodDescriptor md=fm.getMethod();
1614     ParamsObject objectparams=(ParamsObject)paramstable.get(md);
1615     generateHeader(fm, null, md, output);
1616     TempObject objecttemp=(TempObject) tempstable.get(md);
1617
1618
1619     if (GENERATEPRECISEGC) {
1620       output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1621       output.print(objecttemp.numPointers()+",");
1622       output.print(paramsprefix);
1623       for(int j=0; j<objecttemp.numPointers(); j++)
1624         output.print(", NULL");
1625       output.println("};");
1626     }
1627
1628     for(int i=0; i<objecttemp.numPrimitives(); i++) {
1629       TempDescriptor td=objecttemp.getPrimitive(i);
1630       TypeDescriptor type=td.getType();
1631       if (type.isNull())
1632         output.println("   void * "+td.getSafeSymbol()+";");
1633       else if (type.isClass()||type.isArray())
1634         output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1635       else
1636         output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1637     }
1638
1639     
1640     // Check to see if we need to do a GC if this is a
1641     // multi-threaded program...    
1642     if (GENERATEPRECISEGC) {
1643       //Don't bother if we aren't in recursive methods...The loops case will catch it
1644       if (callgraph.getAllMethods(md).contains(md)) {
1645         output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
1646       }
1647     }    
1648
1649
1650     generateCode(seseEnter.getNext(0), fm, null, seseExit, output);
1651
1652     
1653     output.println("}\n\n");
1654   }
1655
1656   protected void generateMethodSESE(FlatSESEEnterNode fsen,
1657                                     LocalityBinding lb,
1658                                     PrintWriter outputStructs,
1659                                     PrintWriter outputMethHead,
1660                                     PrintWriter outputMethods
1661                                     ) {
1662
1663
1664     FlatMethod       fm = fsen.getEnclosingFlatMeth();
1665     MethodDescriptor md = fm.getMethod();
1666     ClassDescriptor  cn = md.getClassDesc();
1667     
1668         
1669     //Creates bogus method descriptor to index into tables
1670     Modifiers bogusmod=new Modifiers();
1671     MethodDescriptor bogusmd=new MethodDescriptor(bogusmod, 
1672                                                   new TypeDescriptor(TypeDescriptor.VOID), 
1673                                                   "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier());
1674     bogusmd.setClassDesc(cn);
1675     FlatMethod bogusfm=new FlatMethod(bogusmd, null);
1676     sese2bogusFlatMeth.put(fsen, bogusfm);
1677
1678
1679     //Build paramsobj for bogus method descriptor
1680     ParamsObject objectparams=new ParamsObject(bogusmd, tag++);
1681     paramstable.put(bogusmd, objectparams);
1682     
1683     for(int i=0; i<fsen.numParameters(); i++) {
1684       TempDescriptor temp=fsen.getParameter(i);
1685       TypeDescriptor type=temp.getType();
1686       if (type.isPtr()&&GENERATEPRECISEGC) {
1687         objectparams.addPtr(temp);
1688       } else {
1689         objectparams.addPrim(temp);
1690       }
1691     }
1692     
1693     
1694     //Build normal temp object for bogus method descriptor
1695     TempObject objecttemps=new TempObject(objectparams,bogusmd,tag++);
1696     tempstable.put(bogusmd, objecttemps);
1697     
1698     for(Iterator nodeit=fsen.getNodeSet().iterator(); nodeit.hasNext();) {
1699       FlatNode fn=(FlatNode)nodeit.next();
1700       TempDescriptor[] writes=fn.writesTemps();
1701       for(int i=0; i<writes.length; i++) {
1702         TempDescriptor temp=writes[i];
1703         TypeDescriptor type=temp.getType();
1704         if (type.isPtr()&&GENERATEPRECISEGC)
1705           objecttemps.addPtr(temp);
1706         else
1707           objecttemps.addPrim(temp);
1708       }
1709     }
1710     
1711     
1712     //Generate code for parameters structure
1713     generateMethodParam(cn, bogusmd, null, outputStructs); 
1714
1715     //Generate code for locals structure
1716     outputStructs.println("struct "+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"_"+bogusmd.getSafeMethodDescriptor()+"_locals {");
1717     outputStructs.println("  INTPTR size;");
1718     outputStructs.println("  void * next;");
1719     for(int i=0; i<objecttemps.numPointers(); i++) {
1720       TempDescriptor temp=objecttemps.getPointer(i);
1721       if (temp.getType().isNull())
1722         outputStructs.println("  void * "+temp.getSafeSymbol()+";");
1723       else
1724         outputStructs.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1725     }
1726     outputStructs.println("};\n");
1727     
1728
1729     // write method declaration to header file
1730     outputMethHead.print("void ");
1731     outputMethHead.print(cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"_"+bogusmd.getSafeMethodDescriptor()+"(");
1732     boolean printcomma=false;
1733     if (GENERATEPRECISEGC) {
1734       outputMethHead.print("struct "+cn.getSafeSymbol()+
1735                            bogusmd.getSafeSymbol()+"_"+
1736                            bogusmd.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1737       printcomma=true;
1738     }
1739     //  Output parameter list
1740     for(int i=0; i<objectparams.numPrimitives(); i++) {
1741       TempDescriptor temp=objectparams.getPrimitive(i);
1742       if (printcomma)
1743         outputMethHead.print(", ");
1744       printcomma=true;
1745       if (temp.getType().isClass()||temp.getType().isArray())
1746         outputMethHead.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1747       else
1748         outputMethHead.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1749     }
1750     outputMethHead.println(");\n");
1751
1752
1753     generateFlatMethodSESE(bogusfm, cn, fsen, fsen.getFlatExit(), outputMethods);
1754   }
1755
1756
1757   protected void generateCode(FlatNode first,
1758                               FlatMethod fm,
1759                               LocalityBinding lb,
1760                               FlatSESEExitNode stop,
1761                               PrintWriter output) {
1762
1763     /* Assign labels to FlatNode's if necessary.*/
1764     Hashtable<FlatNode, Integer> nodetolabel=assignLabels(first, stop);
1765
1766     /* Do the actual code generation */
1767     FlatNode current_node=null;
1768     HashSet tovisit=new HashSet();
1769     HashSet visited=new HashSet();
1770     tovisit.add(first);
1771     while(current_node!=null||!tovisit.isEmpty()) {
1772       if (current_node==null) {
1773         current_node=(FlatNode)tovisit.iterator().next();
1774         tovisit.remove(current_node);
1775       } else if (tovisit.contains(current_node)) {
1776         tovisit.remove(current_node);
1777       }
1778       visited.add(current_node);
1779       if (nodetolabel.containsKey(current_node)) {
1780         output.println("L"+nodetolabel.get(current_node)+":");
1781       }
1782       if (state.INSTRUCTIONFAILURE) {
1783         if (state.THREAD||state.DSM||state.SINGLETM) {
1784           output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1785         } else
1786           output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1787       }
1788       if (current_node.numNext()==0||current_node==stop) {
1789         output.print("   ");
1790         generateFlatNode(fm, lb, current_node, output);
1791         if (current_node.kind()!=FKind.FlatReturnNode) {
1792           output.println("   return;");
1793         }
1794         current_node=null;
1795       } else if(current_node.numNext()==1) {
1796         FlatNode nextnode;
1797         if (state.MLP && current_node.kind()==FKind.FlatSESEEnterNode) {
1798           FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node;
1799           generateFlatNode(fm, lb, current_node, output);
1800           nextnode=fsen.getFlatExit().getNext(0);
1801         } else {
1802           output.print("   ");
1803           generateFlatNode(fm, lb, current_node, output);
1804           nextnode=current_node.getNext(0);
1805         }
1806         if (visited.contains(nextnode)) {
1807           output.println("goto L"+nodetolabel.get(nextnode)+";");
1808           current_node=null;
1809         } else 
1810           current_node=nextnode;
1811       } else if (current_node.numNext()==2) {
1812         /* Branch */
1813         output.print("   ");  
1814         generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1815         if (!visited.contains(current_node.getNext(1)))
1816           tovisit.add(current_node.getNext(1));
1817         if (visited.contains(current_node.getNext(0))) {
1818           output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1819           current_node=null;
1820         } else 
1821           current_node=current_node.getNext(0);
1822       } else throw new Error();
1823     }
1824   }
1825
1826
1827   /** This method assigns labels to FlatNodes */
1828   protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first) {
1829     return assignLabels(first, null);
1830   }
1831   protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first, FlatSESEExitNode last) {
1832     HashSet tovisit=new HashSet();
1833     HashSet visited=new HashSet();
1834     int labelindex=0;
1835     Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
1836     tovisit.add(first);
1837
1838     /*Assign labels first.  A node needs a label if the previous
1839      * node has two exits or this node is a join point. */
1840
1841     while(!tovisit.isEmpty()) {
1842       FlatNode fn=(FlatNode)tovisit.iterator().next();
1843       tovisit.remove(fn);
1844       visited.add(fn);
1845
1846
1847       if( fn.equals(last) ) {
1848         // if last is not null and matches, don't go 
1849         // any further for assigning labels
1850         continue;
1851       }
1852
1853       for(int i=0; i<fn.numNext(); i++) {
1854         FlatNode nn=fn.getNext(i);
1855
1856         if(i>0) {
1857           //1) Edge >1 of node
1858           nodetolabel.put(nn,new Integer(labelindex++));
1859         }
1860         if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1861           tovisit.add(nn);
1862         } else {
1863           //2) Join point
1864           nodetolabel.put(nn,new Integer(labelindex++));
1865         }
1866       }
1867     }
1868     return nodetolabel;
1869   }
1870
1871
1872   /** Generate text string that corresponds to the TempDescriptor td. */
1873   protected String generateTemp(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
1874     MethodDescriptor md=fm.getMethod();
1875     TaskDescriptor task=fm.getTask();
1876     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1877
1878     if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1879       //System.out.println("generateTemp returns " + td.getSafeSymbol());
1880       return td.getSafeSymbol();
1881     }
1882
1883     if (objecttemps.isLocalPtr(td)) {
1884       return localsprefix+"."+td.getSafeSymbol();
1885     }
1886
1887     if (objecttemps.isParamPtr(td)) {
1888       return paramsprefix+"->"+td.getSafeSymbol();
1889     }
1890
1891     throw new Error();
1892   }
1893
1894   protected void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
1895     switch(fn.kind()) {
1896     case FKind.FlatAtomicEnterNode:
1897       generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
1898       return;
1899
1900     case FKind.FlatAtomicExitNode:
1901       generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
1902       return;
1903
1904     case FKind.FlatInstanceOfNode:
1905       generateFlatInstanceOfNode(fm, lb, (FlatInstanceOfNode)fn, output);
1906       return;
1907
1908     case FKind.FlatSESEEnterNode:
1909       generateFlatSESEEnterNode(fm, lb, (FlatSESEEnterNode)fn, output);
1910       return;
1911
1912     case FKind.FlatSESEExitNode:
1913       generateFlatSESEExitNode(fm, lb, (FlatSESEExitNode)fn, output);
1914       return;
1915
1916     case FKind.FlatGlobalConvNode:
1917       generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output);
1918       return;
1919
1920     case FKind.FlatTagDeclaration:
1921       generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output);
1922       return;
1923
1924     case FKind.FlatCall:
1925       generateFlatCall(fm, lb, (FlatCall) fn,output);
1926       return;
1927
1928     case FKind.FlatFieldNode:
1929       generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
1930       return;
1931
1932     case FKind.FlatElementNode:
1933       generateFlatElementNode(fm, lb, (FlatElementNode) fn,output);
1934       return;
1935
1936     case FKind.FlatSetElementNode:
1937       generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output);
1938       return;
1939
1940     case FKind.FlatSetFieldNode:
1941       generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
1942       return;
1943
1944     case FKind.FlatNew:
1945       generateFlatNew(fm, lb, (FlatNew) fn,output);
1946       return;
1947
1948     case FKind.FlatOpNode:
1949       generateFlatOpNode(fm, lb, (FlatOpNode) fn,output);
1950       return;
1951
1952     case FKind.FlatCastNode:
1953       generateFlatCastNode(fm, lb, (FlatCastNode) fn,output);
1954       return;
1955
1956     case FKind.FlatLiteralNode:
1957       generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output);
1958       return;
1959
1960     case FKind.FlatReturnNode:
1961       generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output);
1962       return;
1963
1964     case FKind.FlatNop:
1965       output.println("/* nop */");
1966       return;
1967
1968     case FKind.FlatExit:
1969       output.println("/* exit */");
1970       return;
1971
1972     case FKind.FlatBackEdge:
1973       if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
1974         if(state.DSM&&locality.getAtomic(lb).get(fn).intValue()>0) {
1975           output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
1976         } else
1977           output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
1978       } else
1979         output.println("/* nop */");
1980       return;
1981
1982     case FKind.FlatCheckNode:
1983       generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output);
1984       return;
1985
1986     case FKind.FlatFlagActionNode:
1987       generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
1988       return;
1989
1990     case FKind.FlatPrefetchNode:
1991       generateFlatPrefetchNode(fm,lb, (FlatPrefetchNode) fn, output);
1992       return;
1993
1994     case FKind.FlatOffsetNode:
1995       generateFlatOffsetNode(fm, lb, (FlatOffsetNode)fn, output);
1996       return;
1997     }
1998     throw new Error();
1999   }
2000
2001   public void generateFlatOffsetNode(FlatMethod fm, LocalityBinding lb, FlatOffsetNode fofn, PrintWriter output) {
2002     output.println("/* FlatOffsetNode */");
2003     FieldDescriptor fd=fofn.getField();
2004     output.println(generateTemp(fm, fofn.getDst(),lb)+ " = (short)(int) (&((struct "+fofn.getClassType().getSafeSymbol() +" *)0)->"+ fd.getSafeSymbol()+");");
2005     output.println("/* offset */");
2006   }
2007
2008   public void generateFlatPrefetchNode(FlatMethod fm, LocalityBinding lb, FlatPrefetchNode fpn, PrintWriter output) {
2009     if (state.PREFETCH) {
2010       Vector oids = new Vector();
2011       Vector fieldoffset = new Vector();
2012       Vector endoffset = new Vector();
2013       int tuplecount = 0;        //Keeps track of number of prefetch tuples that need to be generated
2014       for(Iterator it = fpn.hspp.iterator(); it.hasNext();) {
2015         PrefetchPair pp = (PrefetchPair) it.next();
2016         Integer statusbase = locality.getNodePreTempInfo(lb,fpn).get(pp.base);
2017         /* Find prefetches that can generate oid */
2018         if(statusbase == LocalityAnalysis.GLOBAL) {
2019           generateTransCode(fm, lb, pp, oids, fieldoffset, endoffset, tuplecount, locality.getAtomic(lb).get(fpn).intValue()>0, false);
2020           tuplecount++;
2021         } else if (statusbase == LocalityAnalysis.LOCAL) {
2022           generateTransCode(fm,lb,pp,oids,fieldoffset,endoffset,tuplecount,false,true);
2023         } else {
2024           continue;
2025         }
2026       }
2027       if (tuplecount==0)
2028         return;
2029       System.out.println("Adding prefetch "+fpn+ " to method:" +fm);
2030       output.println("{");
2031       output.println("/* prefetch */");
2032       output.println("/* prefetchid_" + fpn.siteid + " */");
2033       output.println("void * prefptr;");
2034       output.println("int tmpindex;");
2035
2036       output.println("if((evalPrefetch["+fpn.siteid+"].operMode) || (evalPrefetch["+fpn.siteid+"].retrycount <= 0)) {");
2037       /*Create C code for oid array */
2038       output.print("   unsigned int oidarray_[] = {");
2039       boolean needcomma=false;
2040       for (Iterator it = oids.iterator(); it.hasNext();) {
2041         if (needcomma)
2042           output.print(", ");
2043         output.print(it.next());
2044         needcomma=true;
2045       }
2046       output.println("};");
2047
2048       /*Create C code for endoffset values */
2049       output.print("   unsigned short endoffsetarry_[] = {");
2050       needcomma=false;
2051       for (Iterator it = endoffset.iterator(); it.hasNext();) {
2052         if (needcomma)
2053           output.print(", ");
2054         output.print(it.next());
2055         needcomma=true;
2056       }
2057       output.println("};");
2058
2059       /*Create C code for Field Offset Values */
2060       output.print("   short fieldarry_[] = {");
2061       needcomma=false;
2062       for (Iterator it = fieldoffset.iterator(); it.hasNext();) {
2063         if (needcomma)
2064           output.print(", ");
2065         output.print(it.next());
2066         needcomma=true;
2067       }
2068       output.println("};");
2069       /* make the prefetch call to Runtime */
2070       output.println("   if(!evalPrefetch["+fpn.siteid+"].operMode) {");
2071       output.println("     evalPrefetch["+fpn.siteid+"].retrycount = RETRYINTERVAL;");
2072       output.println("   }");
2073       output.println("   prefetch("+fpn.siteid+" ,"+tuplecount+", oidarray_, endoffsetarry_, fieldarry_);");
2074       output.println(" } else {");
2075       output.println("   evalPrefetch["+fpn.siteid+"].retrycount--;");
2076       output.println(" }");
2077       output.println("}");
2078     }
2079   }
2080
2081   public void generateTransCode(FlatMethod fm, LocalityBinding lb,PrefetchPair pp, Vector oids, Vector fieldoffset, Vector endoffset, int tuplecount, boolean inside, boolean localbase) {
2082     short offsetcount = 0;
2083     int breakindex=0;
2084     if (inside) {
2085       breakindex=1;
2086     } else if (localbase) {
2087       for(; breakindex<pp.desc.size(); breakindex++) {
2088         Descriptor desc=pp.getDescAt(breakindex);
2089         if (desc instanceof FieldDescriptor) {
2090           FieldDescriptor fd=(FieldDescriptor)desc;
2091           if (fd.isGlobal()) {
2092             break;
2093           }
2094         }
2095       }
2096       breakindex++;
2097     }
2098
2099     if (breakindex>pp.desc.size())     //all local
2100       return;
2101
2102     TypeDescriptor lasttype=pp.base.getType();
2103     String basestr=generateTemp(fm, pp.base, lb);
2104     String teststr="";
2105     boolean maybenull=fm.getMethod().isStatic()||
2106                        !pp.base.equals(fm.getParameter(0));
2107
2108     for(int i=0; i<breakindex; i++) {
2109       String indexcheck="";
2110
2111       Descriptor desc=pp.getDescAt(i);
2112       if (desc instanceof FieldDescriptor) {
2113         FieldDescriptor fd=(FieldDescriptor)desc;
2114         if (maybenull) {
2115           if (!teststr.equals(""))
2116             teststr+="&&";
2117           teststr+="((prefptr="+basestr+")!=NULL)";
2118           basestr="((struct "+lasttype.getSafeSymbol()+" *)prefptr)->"+fd.getSafeSymbol();
2119         } else {
2120           basestr=basestr+"->"+fd.getSafeSymbol();
2121           maybenull=true;
2122         }
2123         lasttype=fd.getType();
2124       } else {
2125         IndexDescriptor id=(IndexDescriptor)desc;
2126         indexcheck="((tmpindex=";
2127         for(int j=0; j<id.tddesc.size(); j++) {
2128           indexcheck+=generateTemp(fm, id.getTempDescAt(j), lb)+"+";
2129         }
2130         indexcheck+=id.offset+")>=0)&(tmpindex<((struct ArrayObject *)prefptr)->___length___)";
2131
2132         if (!teststr.equals(""))
2133           teststr+="&&";
2134         teststr+="((prefptr="+basestr+")!= NULL) &&"+indexcheck;
2135         basestr="((void **)(((char *) &(((struct ArrayObject *)prefptr)->___length___))+sizeof(int)))[tmpindex]";
2136         maybenull=true;
2137         lasttype=lasttype.dereference();
2138       }
2139     }
2140
2141     String oid;
2142     if (teststr.equals("")) {
2143       oid="((unsigned int)"+basestr+")";
2144     } else {
2145       oid="((unsigned int)(("+teststr+")?"+basestr+":NULL))";
2146     }
2147     oids.add(oid);
2148
2149     for(int i = breakindex; i < pp.desc.size(); i++) {
2150       String newfieldoffset;
2151       Object desc = pp.getDescAt(i);
2152       if(desc instanceof FieldDescriptor) {
2153         FieldDescriptor fd=(FieldDescriptor)desc;
2154         newfieldoffset = new String("(unsigned int)(&(((struct "+ lasttype.getSafeSymbol()+" *)0)->"+ fd.getSafeSymbol()+ "))");
2155         lasttype=fd.getType();
2156       } else {
2157         newfieldoffset = "";
2158         IndexDescriptor id=(IndexDescriptor)desc;
2159         for(int j = 0; j < id.tddesc.size(); j++) {
2160           newfieldoffset += generateTemp(fm, id.getTempDescAt(j), lb) + "+";
2161         }
2162         newfieldoffset += id.offset.toString();
2163         lasttype=lasttype.dereference();
2164       }
2165       fieldoffset.add(newfieldoffset);
2166     }
2167
2168     int base=(tuplecount>0) ? ((Short)endoffset.get(tuplecount-1)).intValue() : 0;
2169     base+=pp.desc.size()-breakindex;
2170     endoffset.add(new Short((short)base));
2171   }
2172
2173
2174
2175   public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) {
2176     if (lb!=fgcn.getLocality())
2177       return;
2178     /* Have to generate flat globalconv */
2179     if (fgcn.getMakePtr()) {
2180       if (state.DSM) {
2181         output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
2182       } else {
2183         if ((dc==null)||dc.getNeedTrans(lb, fgcn)) {
2184           //need to do translation
2185           output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+", (void *)&("+localsprefix+"));");
2186         }
2187       }
2188     } else {
2189       /* Need to convert to OID */
2190       if (fgcn.doConvert()) {
2191         output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
2192       } else {
2193         output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=NULL;");
2194       }
2195     }
2196   }
2197
2198   public void generateFlatInstanceOfNode(FlatMethod fm,  LocalityBinding lb, FlatInstanceOfNode fion, PrintWriter output) {
2199     int type;
2200     if (fion.getType().isArray()) {
2201       type=state.getArrayNumber(fion.getType())+state.numClasses();
2202     } else {
2203       type=fion.getType().getClassDesc().getId();
2204     }
2205
2206     if (fion.getType().getSymbol().equals(TypeUtil.ObjectClass))
2207       output.println(generateTemp(fm, fion.getDst(), lb)+"=1;");
2208     else
2209       output.println(generateTemp(fm, fion.getDst(), lb)+"=instanceof("+generateTemp(fm,fion.getSrc(),lb)+","+type+");");
2210   }
2211
2212   public void generateFlatAtomicEnterNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
2213     /* Check to see if we need to generate code for this atomic */
2214     if (locality==null) {
2215       output.println("pthread_mutex_lock(&atomiclock);");
2216       return;
2217     }
2218
2219     if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
2220       return;
2221     /* Backup the temps. */
2222     for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
2223       TempDescriptor tmp=tmpit.next();
2224       output.println(generateTemp(fm, backuptable.get(lb).get(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
2225     }
2226
2227     output.println("goto transstart"+faen.getIdentifier()+";");
2228
2229     /******* Print code to retry aborted transaction *******/
2230     output.println("transretry"+faen.getIdentifier()+":");
2231
2232     /* Restore temps */
2233     for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
2234       TempDescriptor tmp=tmpit.next();
2235       output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(lb).get(tmp),lb)+";");
2236     }
2237
2238     if (state.DSM) {
2239       /********* Need to revert local object store ********/
2240       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2241
2242       output.println("while ("+revertptr+") {");
2243       output.println("struct ___Object___ * tmpptr;");
2244       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
2245       output.println("REVERT_OBJ("+revertptr+");");
2246       output.println(revertptr+"=tmpptr;");
2247       output.println("}");
2248     }
2249     /******* Tell the runtime to start the transaction *******/
2250
2251     output.println("transstart"+faen.getIdentifier()+":");
2252     output.println("transStart();");
2253
2254     if (state.ABORTREADERS) {
2255       output.println("if (_setjmp(aborttrans)) {");
2256       output.println("  goto transretry"+faen.getIdentifier()+"; }");
2257     }
2258   }
2259
2260   public void generateFlatAtomicExitNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
2261     /* Check to see if we need to generate code for this atomic */
2262     if (locality==null) {
2263       output.println("pthread_mutex_unlock(&atomiclock);");
2264       return;
2265     }
2266     if (locality.getAtomic(lb).get(faen).intValue()>0)
2267       return;
2268     //store the revert list before we lose the transaction object
2269     String revertptr=null;
2270     if (state.DSM) {
2271       revertptr=generateTemp(fm, reverttable.get(lb),lb);
2272       output.println(revertptr+"=revertlist;");
2273     }
2274     output.println("if (transCommit()) {");
2275     /* Transaction aborts if it returns true */
2276     output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
2277     if (state.DSM) {
2278       output.println("} else {");
2279       /* Need to commit local object store */
2280       output.println("while ("+revertptr+") {");
2281       output.println("struct ___Object___ * tmpptr;");
2282       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
2283       output.println("COMMIT_OBJ("+revertptr+");");
2284       output.println(revertptr+"=tmpptr;");
2285       output.println("}");
2286     }
2287     output.println("}");
2288   }
2289
2290   public void generateFlatSESEEnterNode(FlatMethod fm,  LocalityBinding lb, FlatSESEEnterNode fsen, PrintWriter output) {
2291     if( !state.MLP ) {
2292       // SESE nodes can be parsed for normal compilation, just skip over them
2293       return;
2294     }
2295     
2296     output.println("\n   /* SESE "+fsen.getPrettyIdentifier()+" issue */");
2297     output.println("   tempSESE = mlpCreateSESErecord( "+
2298                    fsen.getIdentifier()+", "+
2299                    "0, "+
2300                    "mlpGetCurrent(), "+
2301                    fsen.numParameters()+", "+
2302                    "NULL );");
2303
2304     for( int i = 0; i < fsen.numParameters(); ++i ) {
2305       TempDescriptor td   = fsen.getParameter( i );
2306       TypeDescriptor type = td.getType();
2307       output.println("   tempSESE->vars["+i+"].sesetype_"+type.toString()+" = "+td+";");
2308     }
2309
2310     output.println("   mlpIssue( tempSESE );");
2311     output.println("   tempSESE       = mlpSchedule();");
2312     output.println("   tempParentSESE = mlpGetCurrent();");
2313
2314     // do a pthread_create wit invokeSESE as the argument
2315     // and pack all args into a single void*
2316     output.println("   tempSESEargs = (invokeSESEargs*) malloc( sizeof( invokeSESEargs ) );");
2317     output.println("   tempSESEargs->classID = "+fsen.getIdentifier()+";");
2318     output.println("   tempSESEargs->invokee = tempSESE;");
2319     output.println("   tempSESEargs->parent  = tempParentSESE;");
2320
2321     output.println("   invokeSESEmethod( (void*) tempSESEargs );");   
2322     output.println("\n");
2323   }
2324
2325   public void generateFlatSESEExitNode(FlatMethod fm,  LocalityBinding lb, FlatSESEExitNode fsen, PrintWriter output) {
2326     if( !state.MLP ) {
2327       // SESE nodes can be parsed for normal compilation, just skip over them
2328       return;
2329     }
2330   }
2331
2332   private void generateFlatCheckNode(FlatMethod fm,  LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) {
2333     if (state.CONSCHECK) {
2334       String specname=fcn.getSpec();
2335       String varname="repairstate___";
2336       output.println("{");
2337       output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
2338
2339       TempDescriptor[] temps=fcn.getTemps();
2340       String[] vars=fcn.getVars();
2341       for(int i=0; i<temps.length; i++) {
2342         output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i],lb)+";");
2343       }
2344
2345       output.println("if (doanalysis"+specname+"("+varname+")) {");
2346       output.println("free"+specname+"_state("+varname+");");
2347       output.println("} else {");
2348       output.println("/* Bad invariant */");
2349       output.println("free"+specname+"_state("+varname+");");
2350       output.println("abort_task();");
2351       output.println("}");
2352       output.println("}");
2353     }
2354   }
2355
2356   private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
2357     MethodDescriptor md=fc.getMethod();
2358     ParamsObject objectparams=(ParamsObject)paramstable.get(state.DSM||state.SINGLETM ? locality.getBinding(lb, fc) : md);
2359     ClassDescriptor cn=md.getClassDesc();
2360     output.println("{");
2361     if (GENERATEPRECISEGC) {
2362       if (state.DSM||state.SINGLETM) {
2363         LocalityBinding fclb=locality.getBinding(lb, fc);
2364         output.print("       struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2365       } else
2366         output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2367
2368       output.print(objectparams.numPointers());
2369       output.print(", & "+localsprefix);
2370       if (md.getThis()!=null) {
2371         output.print(", ");
2372         output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb));
2373       }
2374       if (fc.getThis()!=null&&md.getThis()==null) {
2375         System.out.println("WARNING!!!!!!!!!!!!");
2376         System.out.println("Source code calls static method "+md+" on an object in "+fm.getMethod()+"!");
2377       }
2378
2379
2380       for(int i=0; i<fc.numArgs(); i++) {
2381         Descriptor var=md.getParameter(i);
2382         TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2383         if (objectparams.isParamPtr(paramtemp)) {
2384           TempDescriptor targ=fc.getArg(i);
2385           output.print(", ");
2386           TypeDescriptor td=md.getParamType(i);
2387           if (td.isTag())
2388             output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
2389           else
2390             output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
2391         }
2392       }
2393       output.println("};");
2394     }
2395     output.print("       ");
2396
2397
2398     if (fc.getReturnTemp()!=null)
2399       output.print(generateTemp(fm,fc.getReturnTemp(),lb)+"=");
2400
2401     /* Do we need to do virtual dispatch? */
2402     if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
2403       //no
2404       if (state.DSM||state.SINGLETM) {
2405         LocalityBinding fclb=locality.getBinding(lb, fc);
2406         output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
2407       } else {
2408         output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
2409       }
2410     } else {
2411       //yes
2412       output.print("((");
2413       if (md.getReturnType().isClass()||md.getReturnType().isArray())
2414         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
2415       else
2416         output.print(md.getReturnType().getSafeSymbol()+" ");
2417       output.print("(*)(");
2418
2419       boolean printcomma=false;
2420       if (GENERATEPRECISEGC) {
2421         if (state.DSM||state.SINGLETM) {
2422           LocalityBinding fclb=locality.getBinding(lb, fc);
2423           output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
2424         } else
2425           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
2426         printcomma=true;
2427       }
2428
2429       for(int i=0; i<objectparams.numPrimitives(); i++) {
2430         TempDescriptor temp=objectparams.getPrimitive(i);
2431         if (printcomma)
2432           output.print(", ");
2433         printcomma=true;
2434         if (temp.getType().isClass()||temp.getType().isArray())
2435           output.print("struct " + temp.getType().getSafeSymbol()+" * ");
2436         else
2437           output.print(temp.getType().getSafeSymbol());
2438       }
2439
2440
2441       if (state.DSM||state.SINGLETM) {
2442         LocalityBinding fclb=locality.getBinding(lb, fc);
2443         output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])");
2444       } else
2445         output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
2446     }
2447
2448     output.print("(");
2449     boolean needcomma=false;
2450     if (GENERATEPRECISEGC) {
2451       output.print("&__parameterlist__");
2452       needcomma=true;
2453     }
2454
2455     if (!GENERATEPRECISEGC) {
2456       if (fc.getThis()!=null) {
2457         TypeDescriptor ptd=md.getThis().getType();
2458         if (needcomma)
2459           output.print(",");
2460         if (ptd.isClass()&&!ptd.isArray())
2461           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2462         output.print(generateTemp(fm,fc.getThis(),lb));
2463         needcomma=true;
2464       }
2465     }
2466
2467     for(int i=0; i<fc.numArgs(); i++) {
2468       Descriptor var=md.getParameter(i);
2469       TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2470       if (objectparams.isParamPrim(paramtemp)) {
2471         TempDescriptor targ=fc.getArg(i);
2472         if (needcomma)
2473           output.print(", ");
2474
2475         TypeDescriptor ptd=md.getParamType(i);
2476         if (ptd.isClass()&&!ptd.isArray())
2477           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2478         output.print(generateTemp(fm, targ,lb));
2479         needcomma=true;
2480       }
2481     }
2482     output.println(");");
2483     output.println("   }");
2484   }
2485
2486   private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
2487     Set subclasses=typeutil.getSubClasses(thiscd);
2488     if (subclasses==null)
2489       return true;
2490     for(Iterator classit=subclasses.iterator(); classit.hasNext();) {
2491       ClassDescriptor cd=(ClassDescriptor)classit.next();
2492       Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
2493       for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
2494         MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
2495         if (md.matches(matchmd))
2496           return false;
2497       }
2498     }
2499     return true;
2500   }
2501
2502   private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) {
2503     if (state.SINGLETM) {
2504       //single machine transactional memory case
2505       String field=ffn.getField().getSafeSymbol();
2506       String src=generateTemp(fm, ffn.getSrc(),lb);
2507       String dst=generateTemp(fm, ffn.getDst(),lb);
2508
2509       output.println(dst+"="+ src +"->"+field+ ";");
2510       if (ffn.getField().getType().isPtr()&&locality.getAtomic(lb).get(ffn).intValue()>0&&
2511           ((dc==null)||dc.getNeedTrans(lb, ffn))&&
2512           locality.getNodePreTempInfo(lb, ffn).get(ffn.getSrc())!=LocalityAnalysis.SCRATCH) {
2513         output.println("TRANSREAD("+dst+", "+dst+", (void *) &(" + localsprefix + "));");
2514       }
2515     } else if (state.DSM) {
2516       Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
2517       if (status==LocalityAnalysis.GLOBAL) {
2518         String field=ffn.getField().getSafeSymbol();
2519         String src=generateTemp(fm, ffn.getSrc(),lb);
2520         String dst=generateTemp(fm, ffn.getDst(),lb);
2521
2522         if (ffn.getField().getType().isPtr()) {
2523
2524           //TODO: Uncomment this when we have runtime support
2525           //if (ffn.getSrc()==ffn.getDst()) {
2526           //output.println("{");
2527           //output.println("void * temp="+src+";");
2528           //output.println("if (temp&0x1) {");
2529           //output.println("temp=(void *) transRead(trans, (unsigned int) temp);");
2530           //output.println(src+"->"+field+"="+temp+";");
2531           //output.println("}");
2532           //output.println(dst+"=temp;");
2533           //output.println("}");
2534           //} else {
2535           output.println(dst+"="+ src +"->"+field+ ";");
2536           //output.println("if ("+dst+"&0x1) {");
2537           output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
2538           //output.println(src+"->"+field+"="+src+"->"+field+";");
2539           //output.println("}");
2540           //}
2541         } else {
2542           output.println(dst+"="+ src+"->"+field+";");
2543         }
2544       } else if (status==LocalityAnalysis.LOCAL) {
2545         if (ffn.getField().getType().isPtr()&&
2546             ffn.getField().isGlobal()) {
2547           String field=ffn.getField().getSafeSymbol();
2548           String src=generateTemp(fm, ffn.getSrc(),lb);
2549           String dst=generateTemp(fm, ffn.getDst(),lb);
2550           output.println(dst+"="+ src +"->"+field+ ";");
2551           if (locality.getAtomic(lb).get(ffn).intValue()>0)
2552             output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
2553         } else
2554           output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
2555       } else if (status==LocalityAnalysis.EITHER) {
2556         //Code is reading from a null pointer
2557         output.println("if ("+generateTemp(fm, ffn.getSrc(),lb)+") {");
2558         output.println("#ifndef RAW");
2559         output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
2560         output.println("#endif");
2561         //This should throw a suitable null pointer error
2562         output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
2563       } else
2564         throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
2565     } else
2566       output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
2567   }
2568
2569
2570   private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) {
2571     if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
2572       throw new Error("Can't set array length");
2573     if (state.SINGLETM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
2574       //Single Machine Transaction Case
2575       boolean srcptr=fsfn.getSrc().getType().isPtr();
2576       String src=generateTemp(fm,fsfn.getSrc(),lb);
2577       String dst=generateTemp(fm,fsfn.getDst(),lb);
2578       if (srcptr&&!fsfn.getSrc().getType().isNull()) {
2579         output.println("{");
2580         if ((dc==null)||dc.getNeedSrcTrans(lb, fsfn)&&
2581             locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getSrc())!=LocalityAnalysis.SCRATCH) {
2582           output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2583         } else {
2584           output.println("INTPTR srcoid=(INTPTR)"+src+";");
2585         }
2586       }
2587       if (wb.needBarrier(fsfn)&&
2588           locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getDst())!=LocalityAnalysis.SCRATCH) {
2589         output.println("*((unsigned int *)&("+dst+"->___objstatus___))|=DIRTY;");
2590       }
2591       if (srcptr&!fsfn.getSrc().getType().isNull()) {
2592         output.println("*((unsigned INTPTR *)&("+dst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
2593         output.println("}");
2594       } else {
2595         output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2596       }
2597     } else if (state.DSM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
2598       Integer statussrc=locality.getNodePreTempInfo(lb,fsfn).get(fsfn.getSrc());
2599       Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
2600       boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
2601
2602       String src=generateTemp(fm,fsfn.getSrc(),lb);
2603       String dst=generateTemp(fm,fsfn.getDst(),lb);
2604       if (srcglobal) {
2605         output.println("{");
2606         output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2607       }
2608       if (statusdst.equals(LocalityAnalysis.GLOBAL)) {
2609         String glbdst=dst;
2610         //mark it dirty
2611         if (wb.needBarrier(fsfn))
2612           output.println("*((unsigned int *)&("+dst+"->___localcopy___))|=DIRTY;");
2613         if (srcglobal) {
2614           output.println("*((unsigned INTPTR *)&("+glbdst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
2615         } else
2616           output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2617       } else if (statusdst.equals(LocalityAnalysis.LOCAL)) {
2618         /** Check if we need to copy */
2619         output.println("if(!"+dst+"->"+localcopystr+") {");
2620         /* Link object into list */
2621         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2622         output.println(revertptr+"=revertlist;");
2623         if (GENERATEPRECISEGC)
2624           output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2625         else
2626           output.println("COPY_OBJ("+dst+");");
2627         output.println(dst+"->"+nextobjstr+"="+revertptr+";");
2628         output.println("revertlist=(struct ___Object___ *)"+dst+";");
2629         output.println("}");
2630         if (srcglobal)
2631           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
2632         else
2633           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2634       } else if (statusdst.equals(LocalityAnalysis.EITHER)) {
2635         //writing to a null...bad
2636         output.println("if ("+dst+") {");
2637         output.println("printf(\"BIG ERROR 2\\n\");exit(-1);}");
2638         if (srcglobal)
2639           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
2640         else
2641           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2642       }
2643       if (srcglobal) {
2644         output.println("}");
2645       }
2646     } else {
2647       if (state.FASTCHECK) {
2648         String dst=generateTemp(fm, fsfn.getDst(),lb);
2649         output.println("if(!"+dst+"->"+localcopystr+") {");
2650         /* Link object into list */
2651         if (GENERATEPRECISEGC)
2652           output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2653         else
2654           output.println("COPY_OBJ("+dst+");");
2655         output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2656         output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2657         output.println("}");
2658       }
2659       output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
2660     }
2661   }
2662
2663   private void generateFlatElementNode(FlatMethod fm, LocalityBinding lb, FlatElementNode fen, PrintWriter output) {
2664     TypeDescriptor elementtype=fen.getSrc().getType().dereference();
2665     String type="";
2666
2667     if (elementtype.isArray()||elementtype.isClass())
2668       type="void *";
2669     else
2670       type=elementtype.getSafeSymbol()+" ";
2671
2672     if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) {
2673       output.println("if ("+generateTemp(fm, fen.getIndex(),lb)+"< 0 | "+generateTemp(fm, fen.getIndex(),lb)+" >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___)");
2674       output.println("failedboundschk();");
2675     }
2676     if (state.SINGLETM) {
2677       //Single machine transaction case
2678       String dst=generateTemp(fm, fen.getDst(),lb);
2679       output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2680
2681       if (elementtype.isPtr()&&locality.getAtomic(lb).get(fen).intValue()>0&&
2682           ((dc==null)||dc.getNeedTrans(lb, fen))&&
2683           locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())!=LocalityAnalysis.SCRATCH) {
2684         output.println("TRANSREAD("+dst+", "+dst+", (void *)&(" + localsprefix+"));");
2685       }
2686     } else if (state.DSM) {
2687       Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc());
2688       if (status==LocalityAnalysis.GLOBAL) {
2689         String dst=generateTemp(fm, fen.getDst(),lb);
2690
2691         if (elementtype.isPtr()) {
2692           output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2693           output.println("TRANSREAD("+dst+", "+dst+");");
2694         } else {
2695           output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2696         }
2697       } else if (status==LocalityAnalysis.LOCAL) {
2698         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2699       } else if (status==LocalityAnalysis.EITHER) {
2700         //Code is reading from a null pointer
2701         output.println("if ("+generateTemp(fm, fen.getSrc(),lb)+") {");
2702         output.println("#ifndef RAW");
2703         output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
2704         output.println("#endif");
2705         //This should throw a suitable null pointer error
2706         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2707       } else
2708         throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
2709     } else {
2710       output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2711     }
2712   }
2713
2714   private void generateFlatSetElementNode(FlatMethod fm, LocalityBinding lb, FlatSetElementNode fsen, PrintWriter output) {
2715     //TODO: need dynamic check to make sure this assignment is actually legal
2716     //Because Object[] could actually be something more specific...ie. Integer[]
2717
2718     TypeDescriptor elementtype=fsen.getDst().getType().dereference();
2719     String type="";
2720
2721     if (elementtype.isArray()||elementtype.isClass())
2722       type="void *";
2723     else
2724       type=elementtype.getSafeSymbol()+" ";
2725
2726     if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) {
2727       output.println("if ("+generateTemp(fm, fsen.getIndex(),lb)+"< 0 | "+generateTemp(fm, fsen.getIndex(),lb)+" >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___)");
2728       output.println("failedboundschk();");
2729     }
2730
2731     if (state.SINGLETM && locality.getAtomic(lb).get(fsen).intValue()>0) {
2732       //Transaction set element case
2733       if (wb.needBarrier(fsen)&&
2734           locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH) {
2735         output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___objstatus___))|=DIRTY;");
2736       }
2737       if (fsen.getSrc().getType().isPtr()&&!fsen.getSrc().getType().isNull()) {
2738         output.println("{");
2739         String src=generateTemp(fm, fsen.getSrc(), lb);
2740         if ((dc==null)||dc.getNeedSrcTrans(lb, fsen)&&
2741             locality.getNodePreTempInfo(lb, fsen).get(fsen.getSrc())!=LocalityAnalysis.SCRATCH) {
2742           output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2743         } else {
2744           output.println("INTPTR srcoid=(INTPTR)"+src+";");
2745         }
2746         output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
2747         output.println("}");
2748       } else {
2749         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
2750       }
2751     } else if (state.DSM && locality.getAtomic(lb).get(fsen).intValue()>0) {
2752       Integer statussrc=locality.getNodePreTempInfo(lb,fsen).get(fsen.getSrc());
2753       Integer statusdst=locality.getNodePreTempInfo(lb,fsen).get(fsen.getDst());
2754       boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
2755       boolean dstglobal=statusdst==LocalityAnalysis.GLOBAL;
2756       boolean dstlocal=statusdst==LocalityAnalysis.LOCAL;
2757
2758       if (dstglobal) {
2759         if (wb.needBarrier(fsen))
2760           output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___localcopy___))|=DIRTY;");
2761       } else if (dstlocal) {
2762         /** Check if we need to copy */
2763         String dst=generateTemp(fm, fsen.getDst(),lb);
2764         output.println("if(!"+dst+"->"+localcopystr+") {");
2765         /* Link object into list */
2766         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2767         output.println(revertptr+"=revertlist;");
2768         if (GENERATEPRECISEGC)
2769           output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2770         else
2771           output.println("COPY_OBJ("+dst+");");
2772         output.println(dst+"->"+nextobjstr+"="+revertptr+";");
2773         output.println("revertlist=(struct ___Object___ *)"+dst+";");
2774         output.println("}");
2775       } else throw new Error("Unknown array type");
2776       if (srcglobal) {
2777         output.println("{");
2778         String src=generateTemp(fm, fsen.getSrc(), lb);
2779         output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2780         output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
2781         output.println("}");
2782       } else {
2783         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
2784       }
2785     } else {
2786       if (state.FASTCHECK) {
2787         String dst=generateTemp(fm, fsen.getDst(),lb);
2788         output.println("if(!"+dst+"->"+localcopystr+") {");
2789         /* Link object into list */
2790         if (GENERATEPRECISEGC)
2791           output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2792         else
2793           output.println("COPY_OBJ("+dst+");");
2794         output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2795         output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2796         output.println("}");
2797       }
2798       output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
2799     }
2800   }
2801
2802   protected void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) {
2803     if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
2804       //Stash pointer in case of GC
2805       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2806       output.println(revertptr+"=revertlist;");
2807     }
2808     if (state.SINGLETM) {
2809       if (fn.getType().isArray()) {
2810         int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
2811         if (locality.getAtomic(lb).get(fn).intValue()>0) {
2812           //inside transaction
2813           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarraytrans(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2814         } else {
2815           //outside transaction
2816           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2817         }
2818       } else {
2819         if (locality.getAtomic(lb).get(fn).intValue()>0) {
2820           //inside transaction
2821           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newtrans(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
2822         } else {
2823           //outside transaction
2824           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
2825         }
2826       }
2827     } else if (fn.getType().isArray()) {
2828       int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
2829       if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
2830         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2831       } else if (GENERATEPRECISEGC) {
2832         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2833       } else {
2834         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2835       }
2836     } else {
2837       if (fn.isGlobal()) {
2838         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal("+fn.getType().getClassDesc().getId()+");");
2839       } else if (GENERATEPRECISEGC) {
2840         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
2841       } else {
2842         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
2843       }
2844     }
2845     if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
2846       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2847       String dst=generateTemp(fm,fn.getDst(),lb);
2848       output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
2849       output.println(dst+"->"+nextobjstr+"="+revertptr+";");
2850       output.println("revertlist=(struct ___Object___ *)"+dst+";");
2851     }
2852     if (state.FASTCHECK) {
2853       String dst=generateTemp(fm,fn.getDst(),lb);
2854       output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
2855       output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2856       output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2857     }
2858   }
2859
2860   private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) {
2861     if (GENERATEPRECISEGC) {
2862       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
2863     } else {
2864       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");");
2865     }
2866   }
2867
2868   private void generateFlatOpNode(FlatMethod fm, LocalityBinding lb, FlatOpNode fon, PrintWriter output) {
2869     if (fon.getRight()!=null) {
2870       if (fon.getOp().getOp()==Operation.URIGHTSHIFT) {
2871         if (fon.getLeft().getType().isLong())
2872           output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
2873         else
2874           output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned int)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
2875
2876       } else
2877         output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";");
2878     } else if (fon.getOp().getOp()==Operation.ASSIGN)
2879       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
2880     else if (fon.getOp().getOp()==Operation.UNARYPLUS)
2881       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
2882     else if (fon.getOp().getOp()==Operation.UNARYMINUS)
2883       output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";");
2884     else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
2885       output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";");
2886     else if (fon.getOp().getOp()==Operation.COMP)
2887       output.println(generateTemp(fm, fon.getDest(),lb)+" = ~"+generateTemp(fm, fon.getLeft(),lb)+";");
2888     else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
2889       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+"->fses==NULL;");
2890     } else
2891       output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";");
2892   }
2893
2894   private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) {
2895     /* TODO: Do type check here */
2896     if (fcn.getType().isArray()) {
2897       throw new Error();
2898     } else if (fcn.getType().isClass())
2899       output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
2900     else
2901       output.println(generateTemp(fm,fcn.getDst(),lb)+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc(),lb)+";");
2902   }
2903
2904   private void generateFlatLiteralNode(FlatMethod fm, LocalityBinding lb, FlatLiteralNode fln, PrintWriter output) {
2905     if (fln.getValue()==null)
2906       output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
2907     else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
2908       if (GENERATEPRECISEGC) {
2909         if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
2910           //Stash pointer in case of GC
2911           String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2912           output.println(revertptr+"=revertlist;");
2913         }
2914         output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
2915         if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
2916           //Stash pointer in case of GC
2917           String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2918           output.println("revertlist="+revertptr+";");
2919         }
2920       } else {
2921         output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
2922       }
2923     } else if (fln.getType().isBoolean()) {
2924       if (((Boolean)fln.getValue()).booleanValue())
2925         output.println(generateTemp(fm, fln.getDst(),lb)+"=1;");
2926       else
2927         output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
2928     } else if (fln.getType().isChar()) {
2929       String st=FlatLiteralNode.escapeString(fln.getValue().toString());
2930       output.println(generateTemp(fm, fln.getDst(),lb)+"='"+st+"';");
2931     } else if (fln.getType().isLong()) {
2932       output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+"LL;");
2933     } else
2934       output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
2935   }
2936
2937   protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
2938     if (frn.getReturnTemp()!=null) {
2939       if (frn.getReturnTemp().getType().isPtr())
2940         output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
2941       else
2942         output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
2943     } else {
2944       output.println("return;");
2945     }
2946   }
2947
2948   protected void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
2949     output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";");
2950   }
2951
2952   /** This method generates header information for the method or
2953    * task referenced by the Descriptor des. */
2954
2955   private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
2956     /* Print header */
2957     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
2958     MethodDescriptor md=null;
2959     TaskDescriptor task=null;
2960     if (des instanceof MethodDescriptor)
2961       md=(MethodDescriptor) des;
2962     else
2963       task=(TaskDescriptor) des;
2964
2965     ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
2966
2967     if (md!=null&&md.getReturnType()!=null) {
2968       if (md.getReturnType().isClass()||md.getReturnType().isArray())
2969         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
2970       else
2971         output.print(md.getReturnType().getSafeSymbol()+" ");
2972     } else
2973       //catch the constructor case
2974       output.print("void ");
2975     if (md!=null) {
2976       if (state.DSM||state.SINGLETM) {
2977         output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
2978       } else
2979         output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
2980     } else
2981       output.print(task.getSafeSymbol()+"(");
2982
2983     boolean printcomma=false;
2984     if (GENERATEPRECISEGC) {
2985       if (md!=null) {
2986         if (state.DSM||state.SINGLETM) {
2987           output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
2988         } else
2989           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
2990       } else
2991         output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
2992       printcomma=true;
2993     }
2994
2995     if (md!=null) {
2996       /* Method */
2997       for(int i=0; i<objectparams.numPrimitives(); i++) {
2998         TempDescriptor temp=objectparams.getPrimitive(i);
2999         if (printcomma)
3000           output.print(", ");
3001         printcomma=true;
3002         if (temp.getType().isClass()||temp.getType().isArray())
3003           output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
3004         else
3005           output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
3006       }
3007       output.println(") {");
3008     } else if (!GENERATEPRECISEGC) {
3009       /* Imprecise Task */
3010       output.println("void * parameterarray[]) {");
3011       /* Unpack variables */
3012       for(int i=0; i<objectparams.numPrimitives(); i++) {
3013         TempDescriptor temp=objectparams.getPrimitive(i);
3014         output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
3015       }
3016       for(int i=0; i<fm.numTags(); i++) {
3017         TempDescriptor temp=fm.getTag(i);
3018         int offset=i+objectparams.numPrimitives();
3019         output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
3020       }
3021
3022       if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
3023         maxtaskparams=objectparams.numPrimitives()+fm.numTags();
3024     } else output.println(") {");
3025   }
3026
3027   public void generateFlatFlagActionNode(FlatMethod fm, LocalityBinding lb, FlatFlagActionNode ffan, PrintWriter output) {
3028     output.println("/* FlatFlagActionNode */");
3029
3030
3031     /* Process tag changes */
3032     Relation tagsettable=new Relation();
3033     Relation tagcleartable=new Relation();
3034
3035     Iterator tagsit=ffan.getTempTagPairs();
3036     while (tagsit.hasNext()) {
3037       TempTagPair ttp=(TempTagPair) tagsit.next();
3038       TempDescriptor objtmp=ttp.getTemp();
3039       TagDescriptor tag=ttp.getTag();
3040       TempDescriptor tagtmp=ttp.getTagTemp();
3041       boolean tagstatus=ffan.getTagChange(ttp);
3042       if (tagstatus) {
3043         tagsettable.put(objtmp, tagtmp);
3044       } else {
3045         tagcleartable.put(objtmp, tagtmp);
3046       }
3047     }
3048
3049
3050     Hashtable flagandtable=new Hashtable();
3051     Hashtable flagortable=new Hashtable();
3052
3053     /* Process flag changes */
3054     Iterator flagsit=ffan.getTempFlagPairs();
3055     while(flagsit.hasNext()) {
3056       TempFlagPair tfp=(TempFlagPair)flagsit.next();
3057       TempDescriptor temp=tfp.getTemp();
3058       Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
3059       FlagDescriptor flag=tfp.getFlag();
3060       if (flag==null) {
3061         //Newly allocate objects that don't set any flags case
3062         if (flagortable.containsKey(temp)) {
3063           throw new Error();
3064         }
3065         int mask=0;
3066         flagortable.put(temp,new Integer(mask));
3067       } else {
3068         int flagid=1<<((Integer)flagtable.get(flag)).intValue();
3069         boolean flagstatus=ffan.getFlagChange(tfp);
3070         if (flagstatus) {
3071           int mask=0;
3072           if (flagortable.containsKey(temp)) {
3073             mask=((Integer)flagortable.get(temp)).intValue();
3074           }
3075           mask|=flagid;
3076           flagortable.put(temp,new Integer(mask));
3077         } else {
3078           int mask=0xFFFFFFFF;
3079           if (flagandtable.containsKey(temp)) {
3080             mask=((Integer)flagandtable.get(temp)).intValue();
3081           }
3082           mask&=(0xFFFFFFFF^flagid);
3083           flagandtable.put(temp,new Integer(mask));
3084         }
3085       }
3086     }
3087
3088
3089     HashSet flagtagset=new HashSet();
3090     flagtagset.addAll(flagortable.keySet());
3091     flagtagset.addAll(flagandtable.keySet());
3092     flagtagset.addAll(tagsettable.keySet());
3093     flagtagset.addAll(tagcleartable.keySet());
3094
3095     Iterator ftit=flagtagset.iterator();
3096     while(ftit.hasNext()) {
3097       TempDescriptor temp=(TempDescriptor)ftit.next();
3098
3099
3100       Set tagtmps=tagcleartable.get(temp);
3101       if (tagtmps!=null) {
3102         Iterator tagit=tagtmps.iterator();
3103         while(tagit.hasNext()) {
3104           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
3105           if (GENERATEPRECISEGC)
3106             output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
3107           else
3108             output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
3109         }
3110       }
3111
3112       tagtmps=tagsettable.get(temp);
3113       if (tagtmps!=null) {
3114         Iterator tagit=tagtmps.iterator();
3115         while(tagit.hasNext()) {
3116           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
3117           if (GENERATEPRECISEGC)
3118             output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
3119           else
3120             output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
3121         }
3122       }
3123
3124       int ormask=0;
3125       int andmask=0xFFFFFFF;
3126
3127       if (flagortable.containsKey(temp))
3128         ormask=((Integer)flagortable.get(temp)).intValue();
3129       if (flagandtable.containsKey(temp))
3130         andmask=((Integer)flagandtable.get(temp)).intValue();
3131       generateFlagOrAnd(ffan, fm, lb, temp, output, ormask, andmask);
3132       generateObjectDistribute(ffan, fm, lb, temp, output);
3133     }
3134   }
3135
3136   protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
3137                                    PrintWriter output, int ormask, int andmask) {
3138     if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
3139       output.println("flagorandinit("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
3140     } else {
3141       output.println("flagorand("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
3142     }
3143   }
3144
3145   protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp, PrintWriter output) {
3146     output.println("enqueueObject("+generateTemp(fm, temp, lb)+");");
3147   }
3148
3149   void generateOptionalHeader(PrintWriter headers) {
3150
3151     //GENERATE HEADERS
3152     headers.println("#include \"task.h\"\n\n");
3153     headers.println("#ifndef _OPTIONAL_STRUCT_");
3154     headers.println("#define _OPTIONAL_STRUCT_");
3155
3156     //STRUCT PREDICATEMEMBER
3157     headers.println("struct predicatemember{");
3158     headers.println("int type;");
3159     headers.println("int numdnfterms;");
3160     headers.println("int * flags;");
3161     headers.println("int numtags;");
3162     headers.println("int * tags;\n};\n\n");
3163
3164     //STRUCT OPTIONALTASKDESCRIPTOR
3165     headers.println("struct optionaltaskdescriptor{");
3166     headers.println("struct taskdescriptor * task;");
3167     headers.println("int index;");
3168     headers.println("int numenterflags;");
3169     headers.println("int * enterflags;");
3170     headers.println("int numpredicatemembers;");
3171     headers.println("struct predicatemember ** predicatememberarray;");
3172     headers.println("};\n\n");
3173
3174     //STRUCT TASKFAILURE
3175     headers.println("struct taskfailure {");
3176     headers.println("struct taskdescriptor * task;");
3177     headers.println("int index;");
3178     headers.println("int numoptionaltaskdescriptors;");
3179     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
3180
3181     //STRUCT FSANALYSISWRAPPER
3182     headers.println("struct fsanalysiswrapper{");
3183     headers.println("int  flags;");
3184     headers.println("int numtags;");
3185     headers.println("int * tags;");
3186     headers.println("int numtaskfailures;");
3187     headers.println("struct taskfailure ** taskfailurearray;");
3188     headers.println("int numoptionaltaskdescriptors;");
3189     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
3190
3191     //STRUCT CLASSANALYSISWRAPPER
3192     headers.println("struct classanalysiswrapper{");
3193     headers.println("int type;");
3194     headers.println("int numotd;");
3195     headers.println("struct optionaltaskdescriptor ** otdarray;");
3196     headers.println("int numfsanalysiswrappers;");
3197     headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
3198
3199     headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
3200
3201     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
3202     while(taskit.hasNext()) {
3203       TaskDescriptor td=(TaskDescriptor)taskit.next();
3204       headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
3205     }
3206
3207   }
3208
3209   //CHECK OVER THIS -- THERE COULD BE SOME ERRORS HERE
3210   int generateOptionalPredicate(Predicate predicate, OptionalTaskDescriptor otd, ClassDescriptor cdtemp, PrintWriter output) {
3211     int predicateindex = 0;
3212     //iterate through the classes concerned by the predicate
3213     Set c_vard = predicate.vardescriptors;
3214     Hashtable<TempDescriptor, Integer> slotnumber=new Hashtable<TempDescriptor, Integer>();
3215     int current_slot=0;
3216
3217     for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();) {
3218       VarDescriptor vard = (VarDescriptor)vard_it.next();
3219       TypeDescriptor typed = vard.getType();
3220
3221       //generate for flags
3222       HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
3223       output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3224       int numberterms=0;
3225       if (fen_hashset!=null) {
3226         for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();) {
3227           FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
3228           if (fen!=null) {
3229             DNFFlag dflag=fen.getDNF();
3230             numberterms+=dflag.size();
3231
3232             Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
3233
3234             for(int j=0; j<dflag.size(); j++) {
3235               if (j!=0)
3236                 output.println(",");
3237               Vector term=dflag.get(j);
3238               int andmask=0;
3239               int checkmask=0;
3240               for(int k=0; k<term.size(); k++) {
3241                 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
3242                 FlagDescriptor fd=dfa.getFlag();
3243                 boolean negated=dfa.getNegated();
3244                 int flagid=1<<((Integer)flags.get(fd)).intValue();
3245                 andmask|=flagid;
3246                 if (!negated)
3247                   checkmask|=flagid;
3248               }
3249               output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
3250             }
3251           }
3252         }
3253       }
3254       output.println("};\n");
3255
3256       //generate for tags
3257       TagExpressionList tagel = predicate.tags.get(vard.getSymbol());
3258       output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3259       int numtags = 0;
3260       if (tagel!=null) {
3261         for(int j=0; j<tagel.numTags(); j++) {
3262           if (j!=0)
3263             output.println(",");
3264           TempDescriptor tmp=tagel.getTemp(j);
3265           if (!slotnumber.containsKey(tmp)) {
3266             Integer slotint=new Integer(current_slot++);
3267             slotnumber.put(tmp,slotint);
3268           }
3269           int slot=slotnumber.get(tmp).intValue();
3270           output.println("/* slot */"+ slot+", /*tagid*/"+state.getTagId(tmp.getTag()));
3271         }
3272         numtags = tagel.numTags();
3273       }
3274       output.println("};");
3275
3276       //store the result into a predicatemember struct
3277       output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
3278       output.println("/*type*/"+typed.getClassDesc().getId()+",");
3279       output.println("/* number of dnf terms */"+numberterms+",");
3280       output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3281       output.println("/* number of tag */"+numtags+",");
3282       output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3283       output.println("};\n");
3284       predicateindex++;
3285     }
3286
3287
3288     //generate an array that stores the entire predicate
3289     output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3290     for( int j = 0; j<predicateindex; j++) {
3291       if( j != predicateindex-1) output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3292       else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3293     }
3294     output.println("};\n");
3295     return predicateindex;
3296   }
3297
3298
3299   void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> safeexecution, Hashtable optionaltaskdescriptors) {
3300     generateOptionalHeader(headers);
3301     //GENERATE STRUCTS
3302     output.println("#include \"optionalstruct.h\"\n\n");
3303     output.println("#include \"stdlib.h\"\n");
3304
3305     HashSet processedcd = new HashSet();
3306     int maxotd=0;
3307     Enumeration e = safeexecution.keys();
3308     while (e.hasMoreElements()) {
3309       int numotd=0;
3310       //get the class
3311       ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
3312       Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);       //will be used several times
3313
3314       //Generate the struct of optionals
3315       Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
3316       numotd = c_otd.size();
3317       if(maxotd<numotd) maxotd = numotd;
3318       if( !c_otd.isEmpty() ) {
3319         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
3320           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
3321
3322           //generate the int arrays for the predicate
3323           Predicate predicate = otd.predicate;
3324           int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
3325           TreeSet<Integer> fsset=new TreeSet<Integer>();
3326           //iterate through possible FSes corresponding to
3327           //the state when entering
3328
3329           for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext();) {
3330             FlagState fs = (FlagState)fses.next();
3331             int flagid=0;
3332             for(Iterator flags = fs.getFlags(); flags.hasNext();) {
3333               FlagDescriptor flagd = (FlagDescriptor)flags.next();
3334               int id=1<<((Integer)flaginfo.get(flagd)).intValue();
3335               flagid|=id;
3336             }
3337             fsset.add(new Integer(flagid));
3338             //tag information not needed because tag
3339             //changes are not tolerated.
3340           }
3341
3342           output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3343           boolean needcomma=false;
3344           for(Iterator<Integer> it=fsset.iterator(); it.hasNext();) {
3345             if(needcomma)
3346               output.print(", ");
3347             output.println(it.next());
3348           }
3349
3350           output.println("};\n");
3351
3352
3353           //generate optionaltaskdescriptor that actually
3354           //includes exit fses, predicate and the task
3355           //concerned
3356           output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
3357           output.println("&task_"+otd.td.getSafeSymbol()+",");
3358           output.println("/*index*/"+otd.getIndex()+",");
3359           output.println("/*number of enter flags*/"+fsset.size()+",");
3360           output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3361           output.println("/*number of members */"+predicateindex+",");
3362           output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3363           output.println("};\n");
3364         }
3365       } else
3366         continue;
3367       // if there are no optionals, there is no need to build the rest of the struct
3368
3369       output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
3370       c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
3371       if( !c_otd.isEmpty() ) {
3372         boolean needcomma=false;
3373         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
3374           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
3375           if(needcomma)
3376             output.println(",");
3377           needcomma=true;
3378           output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3379         }
3380       }
3381       output.println("};\n");
3382
3383       //get all the possible flagstates reachable by an object
3384       Hashtable hashtbtemp = safeexecution.get(cdtemp);
3385       int fscounter = 0;
3386       TreeSet fsts=new TreeSet(new FlagComparator(flaginfo));
3387       fsts.addAll(hashtbtemp.keySet());
3388       for(Iterator fsit=fsts.iterator(); fsit.hasNext();) {
3389         FlagState fs = (FlagState)fsit.next();
3390         fscounter++;
3391
3392         //get the set of OptionalTaskDescriptors corresponding
3393         HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)hashtbtemp.get(fs);
3394         //iterate through the OptionalTaskDescriptors and
3395         //store the pointers to the optionals struct (see on
3396         //top) into an array
3397
3398         output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
3399         for(Iterator<OptionalTaskDescriptor> mos = ordertd(availabletasks).iterator(); mos.hasNext();) {
3400           OptionalTaskDescriptor mm = mos.next();
3401           if(!mos.hasNext())
3402             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
3403           else
3404             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3405         }
3406
3407         output.println("};\n");
3408
3409         //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
3410
3411         int flagid=0;
3412         for(Iterator flags = fs.getFlags(); flags.hasNext();) {
3413           FlagDescriptor flagd = (FlagDescriptor)flags.next();
3414           int id=1<<((Integer)flaginfo.get(flagd)).intValue();
3415           flagid|=id;
3416         }
3417
3418         //process tag information
3419
3420         int tagcounter = 0;
3421         boolean first = true;
3422         Enumeration tag_enum = fs.getTags();
3423         output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
3424         while(tag_enum.hasMoreElements()) {
3425           tagcounter++;
3426           TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement();
3427           if(first==true)
3428             first = false;
3429           else
3430             output.println(", ");
3431           output.println("/*tagid*/"+state.getTagId(tagd));
3432         }
3433         output.println("};");
3434
3435         Set<TaskIndex> tiset=sa.getTaskIndex(fs);
3436         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
3437           TaskIndex ti=itti.next();
3438           if (ti.isRuntime())
3439             continue;
3440
3441           Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
3442
3443           output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
3444           boolean needcomma=false;
3445           for(Iterator<OptionalTaskDescriptor> otdit=ordertd(otdset).iterator(); otdit.hasNext();) {
3446             OptionalTaskDescriptor otd=otdit.next();
3447             if(needcomma)
3448               output.print(", ");
3449             needcomma=true;
3450             output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3451           }
3452           output.println("};");
3453
3454           output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
3455           output.print("&task_"+ti.getTask().getSafeSymbol()+", ");
3456           output.print(ti.getIndex()+", ");
3457           output.print(otdset.size()+", ");
3458           output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
3459           output.println("};");
3460         }
3461
3462         tiset=sa.getTaskIndex(fs);
3463         boolean needcomma=false;
3464         int runtimeti=0;
3465         output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
3466         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
3467           TaskIndex ti=itti.next();
3468           if (ti.isRuntime()) {
3469             runtimeti++;
3470             continue;
3471           }
3472           if (needcomma)
3473             output.print(", ");
3474           needcomma=true;
3475           output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
3476         }
3477         output.println("};\n");
3478
3479         //Store the result in fsanalysiswrapper
3480
3481         output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
3482         output.println("/*flag*/"+flagid+",");
3483         output.println("/* number of tags*/"+tagcounter+",");
3484         output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3485         output.println("/* numtask failures */"+(tiset.size()-runtimeti)+",");
3486         output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3487         output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
3488         output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
3489         output.println("};\n");
3490
3491       }
3492
3493       //Build the array of fsanalysiswrappers
3494       output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
3495       boolean needcomma=false;
3496       for(int i = 0; i<fscounter; i++) {
3497         if (needcomma) output.print(",");
3498         output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
3499         needcomma=true;
3500       }
3501       output.println("};");
3502
3503       //Build the classanalysiswrapper referring to the previous array
3504       output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
3505       output.println("/*type*/"+cdtemp.getId()+",");
3506       output.println("/*numotd*/"+numotd+",");
3507       output.println("otdarray"+cdtemp.getSafeSymbol()+",");
3508       output.println("/* number of fsanalysiswrappers */"+fscounter+",");
3509       output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
3510       processedcd.add(cdtemp);
3511     }
3512
3513     //build an array containing every classes for which code has been build
3514     output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
3515     for(int i=0; i<state.numClasses(); i++) {
3516       ClassDescriptor cn=cdarray[i];
3517       if (i>0)
3518         output.print(", ");
3519       if (processedcd.contains(cn))
3520         output.print("&classanalysiswrapper_"+cn.getSafeSymbol());
3521       else
3522         output.print("NULL");
3523     }
3524     output.println("};");
3525
3526     output.println("#define MAXOTD "+maxotd);
3527     headers.println("#endif");
3528   }
3529
3530   public List<OptionalTaskDescriptor> ordertd(Set<OptionalTaskDescriptor> otdset) {
3531     Relation r=new Relation();
3532     for(Iterator<OptionalTaskDescriptor>otdit=otdset.iterator(); otdit.hasNext();) {
3533       OptionalTaskDescriptor otd=otdit.next();
3534       TaskIndex ti=new TaskIndex(otd.td, otd.getIndex());
3535       r.put(ti, otd);
3536     }
3537
3538     LinkedList<OptionalTaskDescriptor> l=new LinkedList<OptionalTaskDescriptor>();
3539     for(Iterator it=r.keySet().iterator(); it.hasNext();) {
3540       Set s=r.get(it.next());
3541       for(Iterator it2=s.iterator(); it2.hasNext();) {
3542         OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next();
3543         l.add(otd);
3544       }
3545     }
3546
3547     return l;
3548   }
3549
3550   protected void outputTransCode(PrintWriter output) {
3551   }
3552 }
3553
3554
3555
3556
3557
3558