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