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