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