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