more code for support DSM
[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 import Util.Relation;
10 import Analysis.TaskStateAnalysis.FlagState;
11 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
12 import Analysis.TaskStateAnalysis.Predicate;
13 import Analysis.Locality.LocalityAnalysis;
14 import Analysis.Locality.LocalityBinding;
15
16 public class BuildCode {
17     State state;
18     Hashtable temptovar;
19     Hashtable paramstable;
20     Hashtable tempstable;
21     Hashtable fieldorder;
22     Hashtable flagorder;
23     int tag=0;
24     String localsprefix="___locals___";
25     String paramsprefix="___params___";
26     public static boolean GENERATEPRECISEGC=false;
27     public static String PREFIX="";
28     public static String arraytype="ArrayObject";
29     Virtual virtualcalls;
30     TypeUtil typeutil;
31     private int maxtaskparams=0;
32     private int maxcount=0;
33     ClassDescriptor[] cdarray;
34     TypeDescriptor[] arraytable;
35     LocalityAnalysis locality;
36     Hashtable<TempDescriptor, TempDescriptor> backuptable;
37
38     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
39         state=st;
40         this.temptovar=temptovar;
41         paramstable=new Hashtable();    
42         tempstable=new Hashtable();
43         fieldorder=new Hashtable();
44         flagorder=new Hashtable();
45         this.typeutil=typeutil;
46         virtualcalls=new Virtual(state);
47     }
48
49     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality) {
50         this(st, temptovar, typeutil);
51         this.locality=locality;
52         this.backuptable=new Hashtable<TempDescriptor, TempDescriptor>();
53     }
54
55     /** The buildCode method outputs C code for all the methods.  The Flat
56      * versions of the methods must already be generated and stored in
57      * the State object. */
58
59     public void buildCode() {
60         /* Create output streams to write to */
61         PrintWriter outclassdefs=null;
62         PrintWriter outstructs=null;
63         PrintWriter outrepairstructs=null;
64         PrintWriter outmethodheader=null;
65         PrintWriter outmethod=null;
66         PrintWriter outvirtual=null;
67         PrintWriter outtask=null;
68         PrintWriter outtaskdefs=null;
69         PrintWriter outoptionalarrays=null;
70         PrintWriter optionalheaders=null;
71
72         try {
73             outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
74             outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
75             outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
76             outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
77             outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
78             if (state.TASK) {
79                 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
80                 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
81                 if (state.OPTIONAL){
82                     outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
83                     optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
84                 } 
85             }
86             if (state.structfile!=null) {
87                 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
88             }
89         } catch (Exception e) {
90             e.printStackTrace();
91             System.exit(-1);
92         }
93
94         /* Build the virtual dispatch tables */
95         buildVirtualTables(outvirtual);
96
97         /* Output includes */
98         outmethodheader.println("#ifndef METHODHEADERS_H");
99         outmethodheader.println("#define METHODHEADERS_H");
100         outmethodheader.println("#include \"structdefs.h\"");
101
102         /* Output Structures */
103         outputStructs(outstructs);
104
105         // Output the C class declarations
106         // These could mutually reference each other
107         outputClassDeclarations(outclassdefs);
108
109         // Output function prototypes and structures for parameters
110         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
111         while(it.hasNext()) {
112             ClassDescriptor cn=(ClassDescriptor)it.next();
113             generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
114         }
115         outclassdefs.close();
116
117         if (state.TASK) {
118             /* Map flags to integers */
119             /* The runtime keeps track of flags using these integers */
120             it=state.getClassSymbolTable().getDescriptorsIterator();
121             while(it.hasNext()) {
122                 ClassDescriptor cn=(ClassDescriptor)it.next();
123                 mapFlags(cn);
124             }
125             /* Generate Tasks */
126             generateTaskStructs(outstructs, outmethodheader);
127
128             /* Outputs generic task structures if this is a task
129                program */
130             outputTaskTypes(outtask);
131         }
132
133         /* Build the actual methods */
134         outputMethods(outmethod);
135
136         if (state.TASK) {
137             /* Output code for tasks */
138             outputTaskCode(outtaskdefs, outmethod);
139             outtaskdefs.close();
140             /* Record maximum number of task parameters */
141             outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
142         } else if (state.main!=null) {
143             /* Generate main method */
144             outputMainMethod(outmethod);
145         }
146         
147         /* Generate information for task with optional parameters */
148         if (state.TASK&&state.OPTIONAL){
149             generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
150             outoptionalarrays.close();
151         } 
152
153         /* Output structure definitions for repair tool */
154         if (state.structfile!=null) {
155             buildRepairStructs(outrepairstructs);
156             outrepairstructs.close();
157         }
158
159         /* Close files */
160         outmethodheader.println("#endif");
161         outmethodheader.close();
162         outmethod.close();
163         outstructs.println("#endif");
164         outstructs.close();
165     }
166
167     /* This code just generates the main C method for java programs.
168      * The main C method packs up the arguments into a string array
169      * and passes it to the java main method. */
170
171     private void outputMainMethod(PrintWriter outmethod) {
172         outmethod.println("int main(int argc, const char *argv[]) {");
173         outmethod.println("  int i;");
174         if (GENERATEPRECISEGC) {
175             outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
176         } else {
177             outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
178         }
179         if (state.THREAD) {
180             outmethod.println("initializethreads();");
181         }
182         outmethod.println("  for(i=1;i<argc;i++) {");
183         outmethod.println("    int length=strlen(argv[i]);");
184         if (GENERATEPRECISEGC) {
185             outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
186         } else {
187             outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
188         }
189         outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
190         outmethod.println("  }");
191         
192         
193         MethodDescriptor md=typeutil.getMain();
194         ClassDescriptor cd=typeutil.getMainClass();
195         
196         outmethod.println("   {");
197         if (GENERATEPRECISEGC) {
198             outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
199             outmethod.println("1, NULL,"+"stringarray};");
200             outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
201         } else
202             outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
203         outmethod.println("   }");
204         
205         if (state.THREAD) {
206             outmethod.println("pthread_mutex_lock(&gclistlock);");
207             outmethod.println("threadcount--;");
208             outmethod.println("pthread_cond_signal(&gccond);");
209             outmethod.println("pthread_mutex_unlock(&gclistlock);");
210             outmethod.println("pthread_exit(NULL);");
211         }
212         outmethod.println("}");
213     }
214
215     /* This method outputs code for each task. */
216
217     private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
218         /* Compile task based program */
219         outtaskdefs.println("#include \"task.h\"");
220         outtaskdefs.println("#include \"methodheaders.h\"");
221         Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
222         while(taskit.hasNext()) {
223             TaskDescriptor td=(TaskDescriptor)taskit.next();
224             FlatMethod fm=state.getMethodFlat(td);
225             generateFlatMethod(fm, null, outmethod);
226             generateTaskDescriptor(outtaskdefs, fm, td);
227         }
228         
229         //Output task descriptors
230         taskit=state.getTaskSymbolTable().getDescriptorsIterator();
231         outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
232         boolean first=true;
233         while(taskit.hasNext()) {
234             TaskDescriptor td=(TaskDescriptor)taskit.next();
235             if (first)
236                 first=false;
237             else
238                 outtaskdefs.println(",");
239             outtaskdefs.print("&task_"+td.getSafeSymbol());
240         }
241         outtaskdefs.println("};");
242
243         outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
244     }
245
246     /* This method outputs most of the methods.c file.  This includes
247      * some standard includes and then an array with the sizes of
248      * objets and array that stores supertype and then the code for
249      * the Java methods.. */
250
251     private void outputMethods(PrintWriter outmethod) {
252         outmethod.println("#include \"methodheaders.h\"");
253         outmethod.println("#include \"virtualtable.h\"");
254         outmethod.println("#include <runtime.h>");
255         if (state.THREAD)
256             outmethod.println("#include <thread.h>");
257         if (state.main!=null) {
258             outmethod.println("#include <string.h>");       
259         }
260         if (state.CONSCHECK) {
261             outmethod.println("#include \"checkers.h\"");
262         }
263         //Store the sizes of classes & array elements
264         generateSizeArray(outmethod);
265         
266         //Store table of supertypes
267         generateSuperTypeTable(outmethod);
268
269         //Store the layout of classes
270         generateLayoutStructs(outmethod);
271
272         /* Generate code for methods */
273         if (state.DSM) {
274             for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator();lbit.hasNext();) {
275                 LocalityBinding lb=lbit.next();
276                 MethodDescriptor md=lb.getMethod();
277                 FlatMethod fm=state.getMethodFlat(md);
278                 if (!md.getModifiers().isNative()) {
279                     generateFlatMethod(fm, lb, outmethod);
280                 }
281             }
282         } else {
283             Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
284             while(classit.hasNext()) {
285                 ClassDescriptor cn=(ClassDescriptor)classit.next();
286                 Iterator methodit=cn.getMethods();
287                 while(methodit.hasNext()) {
288                     /* Classify parameters */
289                     MethodDescriptor md=(MethodDescriptor)methodit.next();
290                     FlatMethod fm=state.getMethodFlat(md);
291                     if (!md.getModifiers().isNative())
292                         generateFlatMethod(fm, null, outmethod);
293                 }
294             }
295         } 
296     }
297
298     private void outputStructs(PrintWriter outstructs) {
299         outstructs.println("#ifndef STRUCTDEFS_H");
300         outstructs.println("#define STRUCTDEFS_H");
301         outstructs.println("#include \"classdefs.h\"");
302
303         /* Output #defines that the runtime uses to determine type
304          * numbers for various objects it needs */
305
306         outstructs.println("#define STRINGARRAYTYPE "+
307                            (state.getArrayNumber(
308                                                  (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
309
310         outstructs.println("#define OBJECTARRAYTYPE "+
311                            (state.getArrayNumber(
312                                                  (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
313
314
315         outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
316         outstructs.println("#define CHARARRAYTYPE "+
317                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
318
319         outstructs.println("#define BYTEARRAYTYPE "+
320                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
321
322         outstructs.println("#define BYTEARRAYARRAYTYPE "+
323                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
324         
325         outstructs.println("#define NUMCLASSES "+state.numClasses());
326         if (state.TASK) {
327             outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
328             outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
329             outstructs.println("#define TAGARRAYTYPE "+
330                                (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
331         }
332     }
333
334     private void outputClassDeclarations(PrintWriter outclassdefs) {
335         if (state.THREAD)
336             outclassdefs.println("#include <pthread.h>");
337         outclassdefs.println("struct "+arraytype+";");
338         /* Start by declaring all structs */
339         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
340         while(it.hasNext()) {
341             ClassDescriptor cn=(ClassDescriptor)it.next();
342             outclassdefs.println("struct "+cn.getSafeSymbol()+";");
343         }
344         outclassdefs.println("");
345         //Print out definition for array type
346         outclassdefs.println("struct "+arraytype+" {");
347         outclassdefs.println("  int type;");
348         if (state.THREAD) {
349             outclassdefs.println("  pthread_t tid;");
350             outclassdefs.println("  void * lockentry;");
351             outclassdefs.println("  int lockcount;");
352         }
353         if (state.TASK) {
354             outclassdefs.println("  int flag;");
355             outclassdefs.println("  void * flagptr;");
356             if(state.OPTIONAL) 
357                 outclassdefs.println("  int failedstatus;");
358         }
359         printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
360         
361         outclassdefs.println("  int ___length___;");
362         outclassdefs.println("};\n");
363         outclassdefs.println("extern int classsize[];");
364         outclassdefs.println("extern int hasflags[];");
365         outclassdefs.println("extern int * pointerarray[];");
366         outclassdefs.println("extern int supertypes[];");
367     }
368
369     /** Prints out definitions for generic task structures */
370
371     private void outputTaskTypes(PrintWriter outtask) {
372         outtask.println("#ifndef _TASK_H");
373         outtask.println("#define _TASK_H");
374         outtask.println("struct parameterdescriptor {");
375         outtask.println("int type;");
376         outtask.println("int numberterms;");
377         outtask.println("int *intarray;");
378         outtask.println("void * queue;");
379         outtask.println("int numbertags;");
380         outtask.println("int *tagarray;");
381         outtask.println("};");
382         
383         outtask.println("struct taskdescriptor {");
384         outtask.println("void * taskptr;");
385         outtask.println("int numParameters;");
386         outtask.println("int numTotal;");
387         outtask.println("struct parameterdescriptor **descriptorarray;");
388         outtask.println("char * name;");
389         outtask.println("};");
390         outtask.println("extern struct taskdescriptor * taskarray[];");
391         outtask.println("extern numtasks;");
392         outtask.println("#endif");
393     }
394
395
396     private void buildRepairStructs(PrintWriter outrepairstructs) {
397         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
398         while(classit.hasNext()) {
399             ClassDescriptor cn=(ClassDescriptor)classit.next();
400             outrepairstructs.println("structure "+cn.getSymbol()+" {");
401             outrepairstructs.println("  int __type__;");
402             if (state.TASK) {
403                 outrepairstructs.println("  int __flag__;");
404                 outrepairstructs.println("  int __flagptr__;");
405             }
406             printRepairStruct(cn, outrepairstructs);
407             outrepairstructs.println("}\n");
408         }
409         
410         for(int i=0;i<state.numArrays();i++) {
411             TypeDescriptor tdarray=arraytable[i];
412             TypeDescriptor tdelement=tdarray.dereference();
413             outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
414             outrepairstructs.println("  int __type__;");
415             printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
416             outrepairstructs.println("  int length;");
417             /*
418               // Need to add support to repair tool for this
419               if (tdelement.isClass()||tdelement.isArray())
420                 outrepairstructs.println("  "+tdelement.getRepairSymbol()+" * elem[this.length];");
421             else
422                 outrepairstructs.println("  "+tdelement.getRepairSymbol()+" elem[this.length];");
423             */
424             outrepairstructs.println("}\n");
425         }
426     }
427
428     private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
429         ClassDescriptor sp=cn.getSuperDesc();
430         if (sp!=null)
431             printRepairStruct(sp, output);
432         
433         Vector fields=(Vector)fieldorder.get(cn);
434
435         for(int i=0;i<fields.size();i++) {
436             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
437             if (fd.getType().isArray()) {
438                 output.println("  "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
439             } else if (fd.getType().isClass())
440                 output.println("  "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
441             else if (fd.getType().isFloat())
442                 output.println("  int "+fd.getSymbol()+"; /* really float */");
443             else 
444                 output.println("  "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
445         }
446     }
447
448     /** This method outputs TaskDescriptor information */
449     void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
450         for (int i=0;i<task.numParameters();i++) {
451             VarDescriptor param_var=task.getParameter(i);
452             TypeDescriptor param_type=task.getParamType(i);
453             FlagExpressionNode param_flag=task.getFlag(param_var);
454             TagExpressionList param_tag=task.getTag(param_var);
455
456             int dnfterms;
457             if (param_flag==null) {
458                 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
459                 output.println("0x0, 0x0 };");
460                 dnfterms=1;
461             } else {
462                 DNFFlag dflag=param_flag.getDNF();
463                 dnfterms=dflag.size();
464                 
465                 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
466                 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
467                 for(int j=0;j<dflag.size();j++) {
468                     if (j!=0)
469                         output.println(",");
470                     Vector term=dflag.get(j);
471                     int andmask=0;
472                     int checkmask=0;
473                     for(int k=0;k<term.size();k++) {
474                         DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
475                         FlagDescriptor fd=dfa.getFlag();
476                         boolean negated=dfa.getNegated();
477                         int flagid=1<<((Integer)flags.get(fd)).intValue();
478                         andmask|=flagid;
479                         if (!negated)
480                             checkmask|=flagid;
481                     }
482                     output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
483                 }
484                 output.println("};");
485             }
486
487             output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
488             //BUG...added next line to fix, test with any task program
489             if (param_tag!=null)
490                 for(int j=0;j<param_tag.numTags();j++) {
491                     if (j!=0)
492                         output.println(",");
493                     /* for each tag we need */
494                     /* which slot it is */
495                     /* what type it is */
496                     TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
497                     TempDescriptor tmp=param_tag.getTemp(j);
498                     int slot=fm.getTagInt(tmp);
499                     output.println(slot+", "+state.getTagId(tvd.getTag()));
500                 }
501             output.println("};");
502
503             output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
504             output.println("/* type */"+param_type.getClassDesc().getId()+",");
505             output.println("/* number of DNF terms */"+dnfterms+",");
506             output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
507             output.println("0,");
508             //BUG, added next line to fix and else statement...test
509             //with any task program
510             if (param_tag!=null)
511                 output.println("/* number of tags */"+param_tag.numTags()+",");
512             else
513                 output.println("/* number of tags */ 0,");
514             output.println("parametertag_"+i+"_"+task.getSafeSymbol());
515             output.println("};");
516         }
517
518
519         output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
520         for (int i=0;i<task.numParameters();i++) {
521             if (i!=0)
522                 output.println(",");
523             output.print("&parameter_"+i+"_"+task.getSafeSymbol());
524         }
525         output.println("};");
526
527         output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
528         output.println("&"+task.getSafeSymbol()+",");
529         output.println("/* number of parameters */" +task.numParameters() + ",");
530         int numtotal=task.numParameters()+fm.numTags();
531         output.println("/* number total parameters */" +numtotal + ",");
532         output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
533         output.println("\""+task.getSymbol()+"\"");
534         output.println("};");
535     }
536
537
538     /** The buildVirtualTables method outputs the virtual dispatch
539      * tables for methods. */
540
541     private void buildVirtualTables(PrintWriter outvirtual) {
542         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
543         while(classit.hasNext()) {
544             ClassDescriptor cd=(ClassDescriptor)classit.next();
545             if (virtualcalls.getMethodCount(cd)>maxcount)
546                 maxcount=virtualcalls.getMethodCount(cd);
547         }
548         MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
549
550         /* Fill in virtual table */
551         classit=state.getClassSymbolTable().getDescriptorsIterator();
552         while(classit.hasNext()) {
553             ClassDescriptor cd=(ClassDescriptor)classit.next();
554             fillinRow(cd, virtualtable, cd.getId());
555         }
556
557         ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
558         Iterator arrayit=state.getArrayIterator();
559         while(arrayit.hasNext()) {
560             TypeDescriptor td=(TypeDescriptor)arrayit.next();
561             int id=state.getArrayNumber(td);
562             fillinRow(objectcd, virtualtable, id+state.numClasses());
563         }
564         
565         outvirtual.print("void * virtualtable[]={");
566         boolean needcomma=false;
567         for(int i=0;i<state.numClasses()+state.numArrays();i++) {
568             for(int j=0;j<maxcount;j++) {
569                 if (needcomma)
570                     outvirtual.print(", ");
571                 if (virtualtable[i][j]!=null) {
572                     MethodDescriptor md=virtualtable[i][j];
573                     outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
574                 } else {
575                     outvirtual.print("0");
576                 }
577                 needcomma=true;
578             }
579             outvirtual.println("");
580         }
581         outvirtual.println("};");
582         outvirtual.close();
583     }
584
585     private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
586         /* Get inherited methods */
587         if (cd.getSuperDesc()!=null)
588             fillinRow(cd.getSuperDesc(), virtualtable, rownum);
589         /* Override them with our methods */
590         for(Iterator it=cd.getMethods();it.hasNext();) {
591             MethodDescriptor md=(MethodDescriptor)it.next();
592             if (md.isStatic()||md.getReturnType()==null)
593                 continue;
594             int methodnum=virtualcalls.getMethodNumber(md);
595             virtualtable[rownum][methodnum]=md;
596         }
597     }
598
599     /** Generate array that contains the sizes of class objects.  The
600      * object allocation functions in the runtime use this
601      * information. */
602
603     private void generateSizeArray(PrintWriter outclassdefs) {
604         outclassdefs.print("int classsize[]={");
605         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
606         cdarray=new ClassDescriptor[state.numClasses()];
607         while(it.hasNext()) {
608             ClassDescriptor cd=(ClassDescriptor)it.next();
609             cdarray[cd.getId()]=cd;
610         }
611         boolean needcomma=false;
612         for(int i=0;i<state.numClasses();i++) {
613             if (needcomma)
614                 outclassdefs.print(", ");
615             outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");            
616             needcomma=true;
617         }
618
619         arraytable=new TypeDescriptor[state.numArrays()];
620
621         Iterator arrayit=state.getArrayIterator();
622         while(arrayit.hasNext()) {
623             TypeDescriptor td=(TypeDescriptor)arrayit.next();
624             int id=state.getArrayNumber(td);
625             arraytable[id]=td;
626         }
627         
628         for(int i=0;i<state.numArrays();i++) {
629             if (needcomma)
630                 outclassdefs.print(", ");
631             TypeDescriptor tdelement=arraytable[i].dereference();
632             if (tdelement.isArray()||tdelement.isClass())
633                 outclassdefs.print("sizeof(void *)");
634             else
635                 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
636             needcomma=true;
637         }
638
639         outclassdefs.println("};");
640     }
641
642     /** Constructs params and temp objects for each method or task.
643      * These objects tell the compiler which temps need to be
644      * allocated.  */
645
646     private void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
647         MethodDescriptor md=fm.getMethod();
648         TaskDescriptor task=fm.getTask();
649         Set<TempDescriptor> saveset=state.DSM?locality.getTempSet(lb):null;
650         ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++);
651
652         if (md!=null)
653             paramstable.put(md, objectparams);
654         else
655             paramstable.put(task, objectparams);
656
657         for(int i=0;i<fm.numParameters();i++) {
658             TempDescriptor temp=fm.getParameter(i);
659             TypeDescriptor type=temp.getType();
660             if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
661                 objectparams.addPtr(temp);
662             else
663                 objectparams.addPrim(temp);
664             if(state.DSM&&saveset.contains(temp)) {
665                 backuptable.put(temp, temp.createNew());
666             }
667         }
668
669         for(int i=0;i<fm.numTags();i++) {
670             TempDescriptor temp=fm.getTag(i);
671             if (GENERATEPRECISEGC)
672                 objectparams.addPtr(temp);
673             else
674                 objectparams.addPrim(temp);
675         }
676
677         TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
678         if (md!=null)
679             tempstable.put(md, objecttemps);
680         else
681             tempstable.put(task, objecttemps);
682
683         for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
684             FlatNode fn=(FlatNode)nodeit.next();
685             TempDescriptor[] writes=fn.writesTemps();
686             for(int i=0;i<writes.length;i++) {
687                 TempDescriptor temp=writes[i];
688                 TypeDescriptor type=temp.getType();
689                 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
690                     objecttemps.addPtr(temp);
691                 else
692                     objecttemps.addPrim(temp);
693                 if(state.DSM&&saveset.contains(temp)&&
694                    !backuptable.containsKey(temp))
695                     backuptable.put(temp, temp.createNew());
696             }
697         }
698
699         /* Create backup temps */
700         if (state.DSM)
701             for(Iterator<TempDescriptor> tmpit=backuptable.values().iterator();tmpit.hasNext();) {
702                 TempDescriptor tmp=tmpit.next();
703                 TypeDescriptor type=tmp.getType();
704                 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
705                     objecttemps.addPtr(tmp);
706                 else
707                     objecttemps.addPrim(tmp);
708             }
709     }
710
711     /** This method outputs the following information about classes
712      * and arrays:
713      * (1) For classes, what are the locations of pointers.
714      * (2) For arrays, does the array contain pointers or primitives.
715      * (3) For classes, does the class contain flags.
716      */
717
718     private void generateLayoutStructs(PrintWriter output) {
719         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
720         while(it.hasNext()) {
721             ClassDescriptor cn=(ClassDescriptor)it.next();
722             output.println("int "+cn.getSafeSymbol()+"_pointers[]={");
723             Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
724             int count=0;
725             while(allit.hasNext()) {
726                 FieldDescriptor fd=(FieldDescriptor)allit.next();
727                 TypeDescriptor type=fd.getType();
728                 if (type.isPtr()||type.isArray())
729                     count++;
730             }
731             output.print(count);
732             allit=cn.getFieldTable().getAllDescriptorsIterator();
733             while(allit.hasNext()) {
734                 FieldDescriptor fd=(FieldDescriptor)allit.next();
735                 TypeDescriptor type=fd.getType();
736                 if (type.isPtr()||type.isArray()) {
737                     output.println(",");
738                     output.print("((int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
739                 }
740             }
741             output.println("};");
742         }
743         output.println("int * pointerarray[]={");
744         boolean needcomma=false;
745         for(int i=0;i<state.numClasses();i++) {
746             ClassDescriptor cn=cdarray[i];
747             if (needcomma)
748                 output.println(",");
749             needcomma=true;
750             output.print(cn.getSafeSymbol()+"_pointers");
751         }
752
753         for(int i=0;i<state.numArrays();i++) {
754             if (needcomma)
755                 output.println(", ");
756             TypeDescriptor tdelement=arraytable[i].dereference();
757             if (tdelement.isArray()||tdelement.isClass())
758                 output.print("((int *)1)");
759             else
760                 output.print("0");
761             needcomma=true;
762         }
763         
764         output.println("};");
765         needcomma=false;
766         output.println("int hasflags[]={");
767         for(int i=0;i<state.numClasses();i++) {
768             ClassDescriptor cn=cdarray[i];
769             if (needcomma)
770                 output.println(", ");
771             needcomma=true;
772             if (cn.hasFlags())
773                 output.print("1");
774             else
775                 output.print("0");
776         }
777         output.println("};");
778     }
779
780     /** Print out table to give us supertypes */
781     private void generateSuperTypeTable(PrintWriter output) {
782         output.println("int supertypes[]={");
783         boolean needcomma=false;
784         for(int i=0;i<state.numClasses();i++) {
785             ClassDescriptor cn=cdarray[i];
786             if (needcomma)
787                 output.println(",");
788             needcomma=true;
789             if (cn.getSuperDesc()!=null) {
790                 ClassDescriptor cdsuper=cn.getSuperDesc();
791                 output.print(cdsuper.getId());
792             } else
793                 output.print("-1");
794         }
795         output.println("};");
796     }
797
798     /** Force consistent field ordering between inherited classes. */
799
800     private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
801         ClassDescriptor sp=cn.getSuperDesc();
802         if (sp!=null)
803             printClassStruct(sp, classdefout);
804         
805         if (!fieldorder.containsKey(cn)) {
806             Vector fields=new Vector();
807             fieldorder.put(cn,fields);
808             Iterator fieldit=cn.getFields();
809             while(fieldit.hasNext()) {
810                 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
811                 if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
812                     fields.add(fd);
813             }
814         }
815         Vector fields=(Vector)fieldorder.get(cn);
816
817         for(int i=0;i<fields.size();i++) {
818             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
819             if (fd.getType().isClass()||fd.getType().isArray())
820                 classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
821             else 
822                 classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
823         }
824     }
825
826
827     /* Map flags to integers consistently between inherited
828      * classes. */
829
830     private void mapFlags(ClassDescriptor cn) {
831         ClassDescriptor sp=cn.getSuperDesc();
832         if (sp!=null)
833             mapFlags(sp);
834         int max=0;
835         if (!flagorder.containsKey(cn)) {
836             Hashtable flags=new Hashtable();
837             flagorder.put(cn,flags);
838             if (sp!=null) {
839                 Hashtable superflags=(Hashtable)flagorder.get(sp);
840                 Iterator superflagit=superflags.keySet().iterator();
841                 while(superflagit.hasNext()) {
842                     FlagDescriptor fd=(FlagDescriptor)superflagit.next();
843                     Integer number=(Integer)superflags.get(fd);
844                     flags.put(fd, number);
845                     if ((number.intValue()+1)>max)
846                         max=number.intValue()+1;
847                 }
848             }
849             
850             Iterator flagit=cn.getFlags();
851             while(flagit.hasNext()) {
852                 FlagDescriptor fd=(FlagDescriptor)flagit.next();
853                 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
854                     flags.put(fd, new Integer(max++));
855             }
856         }
857     }
858
859
860     /** This function outputs (1) structures that parameters are
861      * passed in (when PRECISE GC is enabled) and (2) function
862      * prototypes for the methods */
863
864     private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
865         /* Output class structure */
866         classdefout.println("struct "+cn.getSafeSymbol()+" {");
867         classdefout.println("  int type;");
868         if (state.THREAD) {
869             classdefout.println("  pthread_t tid;");
870             classdefout.println("  void * lockentry;");
871             classdefout.println("  int lockcount;");
872         }
873
874         if (state.TASK) {
875             classdefout.println("  int flag;");
876             classdefout.println("  void * flagptr;");
877             if (state.OPTIONAL) classdefout.println("  int failedstatus;");
878         }
879         printClassStruct(cn, classdefout);
880         classdefout.println("};\n");
881
882         if (state.DSM) {
883             /* Cycle through LocalityBindings */
884             for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cn).iterator();lbit.hasNext();) {
885                 LocalityBinding lb=lbit.next();
886                 MethodDescriptor md=lb.getMethod();
887                 generateMethod(cn, md, lb, headersout, output);
888             }
889         } else {
890             /* Cycle through methods */
891             for(Iterator methodit=cn.getMethods();methodit.hasNext();) {
892                 /* Classify parameters */
893                 MethodDescriptor md=(MethodDescriptor)methodit.next();
894                 generateMethod(cn, md, null, headersout, output);
895             }
896         }
897     }
898
899     private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
900         FlatMethod fm=state.getMethodFlat(md);
901         generateTempStructs(fm, null);
902         
903         ParamsObject objectparams=(ParamsObject) paramstable.get(md);
904         TempObject objecttemps=(TempObject) tempstable.get(md);
905         
906         /* Output parameter structure */
907         if (GENERATEPRECISEGC) {
908             output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
909             output.println("  int size;");
910             output.println("  void * next;");
911             for(int i=0;i<objectparams.numPointers();i++) {
912                 TempDescriptor temp=objectparams.getPointer(i);
913                 output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
914             }
915             output.println("};\n");
916         }
917         
918         /* Output temp structure */
919         if (GENERATEPRECISEGC) {
920             output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
921             output.println("  int size;");
922             output.println("  void * next;");
923             for(int i=0;i<objecttemps.numPointers();i++) {
924                 TempDescriptor temp=objecttemps.getPointer(i);
925                 if (temp.getType().isNull())
926                     output.println("  void * "+temp.getSafeSymbol()+";");
927                 else
928                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
929             }
930             output.println("};\n");
931         }
932         
933         /********* Output method declaration ***********/
934
935         /* First the return type */
936         if (md.getReturnType()!=null) {
937             if (md.getReturnType().isClass()||md.getReturnType().isArray())
938                 headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
939             else
940                 headersout.print(md.getReturnType().getSafeSymbol()+" ");
941         } else 
942             //catch the constructor case
943             headersout.print("void ");
944
945         /* Next the method name */
946         if (state.DSM) {
947             headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
948         } else
949             headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
950         
951         boolean printcomma=false;
952         if (GENERATEPRECISEGC) {
953             headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
954             printcomma=true;
955         }
956         
957         if (state.DSM&&lb.isAtomic()) {
958             if (printcomma)
959                 headersout.print(", ");
960             headersout.print("transrecord_t * trans");
961             printcomma=true;
962         }
963
964         /*  Output parameter list*/
965         for(int i=0;i<objectparams.numPrimitives();i++) {
966             TempDescriptor temp=objectparams.getPrimitive(i);
967             if (printcomma)
968                 headersout.print(", ");
969             printcomma=true;
970             if (temp.getType().isClass()||temp.getType().isArray())
971                 headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
972             else
973                 headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
974         }
975         headersout.println(");\n");
976     }
977
978
979     /** This function outputs (1) structures that parameters are
980      * passed in (when PRECISE GC is enabled) and (2) function
981      * prototypes for the tasks */
982
983     private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
984         /* Cycle through tasks */
985         Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
986
987         while(taskit.hasNext()) {
988             /* Classify parameters */
989             TaskDescriptor task=(TaskDescriptor)taskit.next();
990             FlatMethod fm=state.getMethodFlat(task);
991             generateTempStructs(fm, null);
992
993             ParamsObject objectparams=(ParamsObject) paramstable.get(task);
994             TempObject objecttemps=(TempObject) tempstable.get(task);
995
996             /* Output parameter structure */
997             if (GENERATEPRECISEGC) {
998                 output.println("struct "+task.getSafeSymbol()+"_params {");
999
1000                 output.println("  int size;");
1001                 output.println("  void * next;");
1002                 for(int i=0;i<objectparams.numPointers();i++) {
1003                     TempDescriptor temp=objectparams.getPointer(i);
1004                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1005                 }
1006
1007                 output.println("};\n");
1008                 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1009                     maxtaskparams=objectparams.numPointers()+fm.numTags();
1010                 }
1011             }
1012
1013             /* Output temp structure */
1014             if (GENERATEPRECISEGC) {
1015                 output.println("struct "+task.getSafeSymbol()+"_locals {");
1016                 output.println("  int size;");
1017                 output.println("  void * next;");
1018                 for(int i=0;i<objecttemps.numPointers();i++) {
1019                     TempDescriptor temp=objecttemps.getPointer(i);
1020                     if (temp.getType().isNull())
1021                         output.println("  void * "+temp.getSafeSymbol()+";");
1022                     else if(temp.getType().isTag())
1023                         output.println("  struct "+
1024                                        (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1025                     else
1026                         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1027                 }
1028                 output.println("};\n");
1029             }
1030             
1031             /* Output task declaration */
1032             headersout.print("void " + task.getSafeSymbol()+"(");
1033             
1034             boolean printcomma=false;
1035             if (GENERATEPRECISEGC) {
1036                 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1037             } else
1038                 headersout.print("void * parameterarray[]");
1039             headersout.println(");\n");
1040         }
1041     }
1042
1043     /** Generate code for FlatMethod fm. */
1044
1045     private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1046         MethodDescriptor md=fm.getMethod();
1047         TaskDescriptor task=fm.getTask();
1048
1049         ClassDescriptor cn=md!=null?md.getClassDesc():null;
1050
1051         ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
1052         generateHeader(fm, lb, md!=null?md:task,output);
1053         TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
1054         if (state.DSM&&lb.getHasAtomic()) {
1055             output.println("transrecord_t * trans;");
1056         }
1057
1058         if (GENERATEPRECISEGC) {
1059             if (md!=null)
1060                 output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1061             else
1062                 output.print("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1063
1064             output.print(objecttemp.numPointers()+",");
1065             output.print(paramsprefix);
1066             for(int j=0;j<objecttemp.numPointers();j++)
1067                 output.print(", NULL");
1068             output.println("};");
1069         }
1070
1071         for(int i=0;i<objecttemp.numPrimitives();i++) {
1072             TempDescriptor td=objecttemp.getPrimitive(i);
1073             TypeDescriptor type=td.getType();
1074             if (type.isNull())
1075                 output.println("   void * "+td.getSafeSymbol()+";");
1076             else if (type.isClass()||type.isArray())
1077                 output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1078             else
1079                 output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1080         }
1081
1082         /* Assign labels to FlatNode's if necessary.*/
1083
1084         Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm);
1085
1086         /* Check to see if we need to do a GC if this is a
1087          * multi-threaded program...*/
1088
1089         if (state.THREAD&&GENERATEPRECISEGC) {
1090             output.println("checkcollect(&"+localsprefix+");");
1091         }
1092         
1093         /* Do the actual code generation */
1094         FlatNode current_node=null;
1095         HashSet tovisit=new HashSet();
1096         HashSet visited=new HashSet();
1097         tovisit.add(fm.getNext(0));
1098         while(current_node!=null||!tovisit.isEmpty()) {
1099             if (current_node==null) {
1100                 current_node=(FlatNode)tovisit.iterator().next();
1101                 tovisit.remove(current_node);
1102             }
1103             visited.add(current_node);
1104             if (nodetolabel.containsKey(current_node))
1105                 output.println("L"+nodetolabel.get(current_node)+":");
1106             if (state.INSTRUCTIONFAILURE) {
1107                 if (state.THREAD) {
1108                     output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1109                 }
1110                 else
1111                     output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1112             }
1113             if (current_node.numNext()==0) {
1114                 output.print("   ");
1115                 generateFlatNode(fm, lb, current_node, output);
1116                 if (current_node.kind()!=FKind.FlatReturnNode) {
1117                     output.println("   return;");
1118                 }
1119                 current_node=null;
1120             } else if(current_node.numNext()==1) {
1121                 output.print("   ");
1122                 generateFlatNode(fm, lb, current_node, output);
1123                 FlatNode nextnode=current_node.getNext(0);
1124                 if (visited.contains(nextnode)) {
1125                     output.println("goto L"+nodetolabel.get(nextnode)+";");
1126                     current_node=null;
1127                 } else
1128                     current_node=nextnode;
1129             } else if (current_node.numNext()==2) {
1130                 /* Branch */
1131                 output.print("   ");
1132                 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1133                 if (!visited.contains(current_node.getNext(1)))
1134                     tovisit.add(current_node.getNext(1));
1135                 if (visited.contains(current_node.getNext(0))) {
1136                     output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1137                     current_node=null;
1138                 } else
1139                     current_node=current_node.getNext(0);
1140             } else throw new Error();
1141         }
1142
1143         output.println("}\n\n");
1144     }
1145
1146     /** This method assigns labels to FlatNodes */
1147
1148     private Hashtable<FlatNode, Integer> assignLabels(FlatMethod fm) {
1149         HashSet tovisit=new HashSet();
1150         HashSet visited=new HashSet();
1151         int labelindex=0;
1152         Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
1153         tovisit.add(fm.getNext(0));
1154
1155         /*Assign labels first.  A node needs a label if the previous
1156          * node has two exits or this node is a join point. */
1157
1158         while(!tovisit.isEmpty()) {
1159             FlatNode fn=(FlatNode)tovisit.iterator().next();
1160             tovisit.remove(fn);
1161             visited.add(fn);
1162             for(int i=0;i<fn.numNext();i++) {
1163                 FlatNode nn=fn.getNext(i);
1164                 if(i>0) {
1165                     //1) Edge >1 of node
1166                     nodetolabel.put(nn,new Integer(labelindex++));
1167                 }
1168                 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1169                     tovisit.add(nn);
1170                 } else {
1171                     //2) Join point
1172                     nodetolabel.put(nn,new Integer(labelindex++));
1173                 }
1174             }
1175         }
1176         return nodetolabel;
1177     }
1178
1179
1180     /** Generate text string that corresponds to the TempDescriptor td. */
1181     private String generateTemp(FlatMethod fm, TempDescriptor td) {
1182         MethodDescriptor md=fm.getMethod();
1183         TaskDescriptor task=fm.getTask();
1184         TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task);
1185
1186         if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1187             return td.getSafeSymbol();
1188         }
1189
1190         if (objecttemps.isLocalPtr(td)) {
1191             return localsprefix+"."+td.getSafeSymbol();
1192         }
1193
1194         if (objecttemps.isParamPtr(td)) {
1195             return paramsprefix+"->"+td.getSafeSymbol();
1196         }
1197         throw new Error();
1198     }
1199
1200     private void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
1201         switch(fn.kind()) {
1202         case FKind.FlatAtomicEnterNode:
1203             generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
1204             return;
1205         case FKind.FlatAtomicExitNode:
1206             generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
1207             return;
1208         case FKind.FlatTagDeclaration:
1209             generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output);
1210             return;
1211         case FKind.FlatCall:
1212             generateFlatCall(fm, (FlatCall) fn,output);
1213             return;
1214         case FKind.FlatFieldNode:
1215             generateFlatFieldNode(fm, (FlatFieldNode) fn,output);
1216             return;
1217         case FKind.FlatElementNode:
1218             generateFlatElementNode(fm, (FlatElementNode) fn,output);
1219             return;
1220         case FKind.FlatSetElementNode:
1221             generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output);
1222             return;
1223         case FKind.FlatSetFieldNode:
1224             generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output);
1225             return;
1226         case FKind.FlatNew:
1227             generateFlatNew(fm, (FlatNew) fn,output);
1228             return;
1229         case FKind.FlatOpNode:
1230             generateFlatOpNode(fm, (FlatOpNode) fn,output);
1231             return;
1232         case FKind.FlatCastNode:
1233             generateFlatCastNode(fm, (FlatCastNode) fn,output);
1234             return;
1235         case FKind.FlatLiteralNode:
1236             generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
1237             return;
1238         case FKind.FlatReturnNode:
1239             generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
1240             return;
1241         case FKind.FlatNop:
1242             output.println("/* nop */");
1243             return;
1244         case FKind.FlatBackEdge:
1245             if (state.THREAD&&GENERATEPRECISEGC) {
1246                 output.println("checkcollect(&"+localsprefix+");");
1247             } else
1248                 output.println("/* nop */");
1249             return;
1250         case FKind.FlatCheckNode:
1251             generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
1252             return;
1253         case FKind.FlatFlagActionNode:
1254             generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output);
1255             return;
1256         }
1257         throw new Error();
1258
1259     }
1260     
1261     public void generateFlatAtomicEnterNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
1262         /* Check to see if we need to generate code for this atomic */
1263         if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
1264             return;
1265         /* Backup the temps. */
1266         for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1267             TempDescriptor tmp=tmpit.next();
1268             output.println(generateTemp(fm, backuptable.get(tmp))+"="+generateTemp(fm,tmp)+";");
1269         }
1270         output.println("goto transstart"+faen.getIdentifier()+";");
1271
1272         /******* Print code to abort transaction *******/
1273         output.println("transabort"+faen.getIdentifier()+":");
1274
1275         /* Restore temps */
1276         for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1277             TempDescriptor tmp=tmpit.next();
1278             output.println(generateTemp(fm, tmp)+"="+generateTemp(fm,backuptable.get(tmp))+";");
1279         }
1280
1281         /******* Tell the runtime to start the transaction *******/
1282         
1283         output.println("transstart"+faen.getIdentifier()+":");
1284         output.println("trans=transStart();");
1285     }
1286
1287     public void generateFlatAtomicExitNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
1288         /* Check to see if we need to generate code for this atomic */
1289         if (locality.getAtomic(lb).get(faen).intValue()>0)
1290             return;
1291
1292     }
1293
1294     private void generateFlatCheckNode(FlatMethod fm,  FlatCheckNode fcn, PrintWriter output) {
1295         if (state.CONSCHECK) {
1296             String specname=fcn.getSpec();
1297             String varname="repairstate___";
1298             output.println("{");
1299             output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
1300
1301             TempDescriptor[] temps=fcn.getTemps();
1302             String[] vars=fcn.getVars();
1303             for(int i=0;i<temps.length;i++) {
1304                 output.println(varname+"->"+vars[i]+"=(int)"+generateTemp(fm, temps[i])+";");
1305             }
1306
1307             output.println("if (doanalysis"+specname+"("+varname+")) {");
1308             output.println("free"+specname+"_state("+varname+");");
1309             output.println("} else {");
1310             output.println("/* Bad invariant */");
1311             output.println("free"+specname+"_state("+varname+");");
1312             output.println("abort_task();");
1313             output.println("}");
1314             output.println("}");
1315         }
1316     }
1317
1318     private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
1319         MethodDescriptor md=fc.getMethod();
1320         ParamsObject objectparams=(ParamsObject) paramstable.get(md);
1321         ClassDescriptor cn=md.getClassDesc();
1322         output.println("{");
1323         if (GENERATEPRECISEGC) {
1324             output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1325             
1326             output.print(objectparams.numPointers());
1327             //      output.print(objectparams.getUID());
1328             output.print(", & "+localsprefix);
1329             if (fc.getThis()!=null) {
1330                 output.print(", ");
1331                 output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis()));
1332             }
1333             for(int i=0;i<fc.numArgs();i++) {
1334                 Descriptor var=md.getParameter(i);
1335                 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1336                 if (objectparams.isParamPtr(paramtemp)) {
1337                     TempDescriptor targ=fc.getArg(i);
1338                     output.print(", ");
1339                     TypeDescriptor td=md.getParamType(i);
1340                     if (td.isTag())
1341                         output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
1342                     else
1343                         output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
1344                 }
1345             }
1346             output.println("};");
1347         }
1348         output.print("       ");
1349
1350
1351         if (fc.getReturnTemp()!=null)
1352             output.print(generateTemp(fm,fc.getReturnTemp())+"=");
1353
1354         /* Do we need to do virtual dispatch? */
1355         if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
1356             output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1357         } else {
1358             output.print("((");
1359             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1360                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1361             else
1362                 output.print(md.getReturnType().getSafeSymbol()+" ");
1363             output.print("(*)(");
1364
1365             boolean printcomma=false;
1366             if (GENERATEPRECISEGC) {
1367                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1368                 printcomma=true;
1369             } 
1370
1371
1372             for(int i=0;i<objectparams.numPrimitives();i++) {
1373                 TempDescriptor temp=objectparams.getPrimitive(i);
1374                 if (printcomma)
1375                     output.print(", ");
1376                 printcomma=true;
1377                 if (temp.getType().isClass()||temp.getType().isArray())
1378                     output.print("struct " + temp.getType().getSafeSymbol()+" * ");
1379                 else
1380                     output.print(temp.getType().getSafeSymbol());
1381             }
1382
1383             output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
1384         }
1385
1386         output.print("(");
1387         boolean needcomma=false;
1388         if (GENERATEPRECISEGC) {
1389             output.print("&__parameterlist__");
1390             needcomma=true;
1391         } else {
1392             if (fc.getThis()!=null) {
1393                 TypeDescriptor ptd=md.getThis().getType();
1394                 if (ptd.isClass()&&!ptd.isArray())
1395                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1396                 output.print(generateTemp(fm,fc.getThis()));
1397                 needcomma=true;
1398             }
1399         }
1400         for(int i=0;i<fc.numArgs();i++) {
1401             Descriptor var=md.getParameter(i);
1402             TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1403             if (objectparams.isParamPrim(paramtemp)) {
1404                 TempDescriptor targ=fc.getArg(i);
1405                 if (needcomma)
1406                     output.print(", ");
1407
1408                 TypeDescriptor ptd=md.getParamType(i);
1409                 if (ptd.isClass()&&!ptd.isArray())
1410                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1411                 output.print(generateTemp(fm, targ));
1412                 needcomma=true;
1413             }
1414         }
1415         output.println(");");
1416         output.println("   }");
1417     }
1418
1419     private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
1420         Set subclasses=typeutil.getSubClasses(thiscd);
1421         if (subclasses==null)
1422             return true;
1423         for(Iterator classit=subclasses.iterator();classit.hasNext();) {
1424             ClassDescriptor cd=(ClassDescriptor)classit.next();
1425             Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
1426             for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
1427                 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
1428                 if (md.matches(matchmd))
1429                     return false;
1430             }
1431         }
1432         return true;
1433     }
1434
1435     private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
1436         output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
1437     }
1438
1439     private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
1440         if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
1441             throw new Error("Can't set array length");
1442         output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
1443     }
1444
1445     private void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
1446         TypeDescriptor elementtype=fen.getSrc().getType().dereference();
1447         String type="";
1448
1449         if (elementtype.isArray()||elementtype.isClass())
1450             type="void *";
1451         else 
1452             type=elementtype.getSafeSymbol()+" ";
1453
1454         if (fen.needsBoundsCheck()) {
1455             output.println("if ("+generateTemp(fm, fen.getIndex())+"< 0 || "+generateTemp(fm, fen.getIndex())+" >= "+generateTemp(fm,fen.getSrc()) + "->___length___)");
1456             output.println("failedboundschk();");
1457         }
1458
1459         output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
1460     }
1461
1462     private void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
1463         //TODO: need dynamic check to make sure this assignment is actually legal
1464         //Because Object[] could actually be something more specific...ie. Integer[]
1465
1466         TypeDescriptor elementtype=fsen.getDst().getType().dereference();
1467         String type="";
1468
1469         if (elementtype.isArray()||elementtype.isClass())
1470             type="void *";
1471         else 
1472             type=elementtype.getSafeSymbol()+" ";
1473
1474         if (fsen.needsBoundsCheck()) {
1475             output.println("if ("+generateTemp(fm, fsen.getIndex())+"< 0 || "+generateTemp(fm, fsen.getIndex())+" >= "+generateTemp(fm,fsen.getDst()) + "->___length___)");
1476             output.println("failedboundschk();");
1477         }
1478
1479         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
1480     }
1481
1482     private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
1483         if (fn.getType().isArray()) {
1484             int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
1485             if (GENERATEPRECISEGC) {
1486                 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1487             } else {
1488                 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1489             }
1490         } else {
1491             if (GENERATEPRECISEGC) {
1492                 output.println(generateTemp(fm,fn.getDst())+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
1493             } else {
1494                 output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
1495             }
1496         }
1497     }
1498
1499
1500     private void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) {
1501         if (GENERATEPRECISEGC) {
1502             output.println(generateTemp(fm,fn.getDst())+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
1503         } else {
1504             output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");");
1505         }
1506     }
1507
1508     private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
1509
1510         if (fon.getRight()!=null)
1511             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
1512         else if (fon.getOp().getOp()==Operation.ASSIGN)
1513             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1514         else if (fon.getOp().getOp()==Operation.UNARYPLUS)
1515             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1516         else if (fon.getOp().getOp()==Operation.UNARYMINUS)
1517             output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
1518         else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
1519             output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";");
1520         else
1521             output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
1522     }
1523
1524     private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
1525         /* TODO: Do type check here */
1526         if (fcn.getType().isArray()) {
1527             throw new Error();
1528         } else if (fcn.getType().isClass())
1529             output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";");
1530         else
1531             output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
1532     }
1533
1534     private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
1535         if (fln.getValue()==null)
1536             output.println(generateTemp(fm, fln.getDst())+"=0;");
1537         else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
1538             if (GENERATEPRECISEGC) {
1539                 output.println(generateTemp(fm, fln.getDst())+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1540             } else {
1541                 output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1542             }
1543         } else if (fln.getType().isBoolean()) {
1544             if (((Boolean)fln.getValue()).booleanValue())
1545                 output.println(generateTemp(fm, fln.getDst())+"=1;");
1546             else
1547                 output.println(generateTemp(fm, fln.getDst())+"=0;");
1548         } else if (fln.getType().isChar()) {
1549             String st=FlatLiteralNode.escapeString(fln.getValue().toString());
1550             output.println(generateTemp(fm, fln.getDst())+"='"+st+"';");
1551         } else
1552             output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
1553     }
1554
1555     private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
1556         if (frn.getReturnTemp()!=null)
1557             output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
1558         else
1559             output.println("return;");
1560     }
1561
1562     private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
1563         output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
1564     }
1565
1566     /** This method generates header information for the method or
1567      * task referenced by the Descriptor des. */
1568
1569     private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
1570         /* Print header */
1571         ParamsObject objectparams=(ParamsObject)paramstable.get(des);
1572         MethodDescriptor md=null;
1573         TaskDescriptor task=null;
1574         if (des instanceof MethodDescriptor)
1575             md=(MethodDescriptor) des;
1576         else
1577             task=(TaskDescriptor) des;
1578
1579         ClassDescriptor cn=md!=null?md.getClassDesc():null;
1580         
1581         if (md!=null&&md.getReturnType()!=null) {
1582             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1583                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1584             else
1585                 output.print(md.getReturnType().getSafeSymbol()+" ");
1586         } else 
1587             //catch the constructor case
1588             output.print("void ");
1589         if (md!=null) {
1590             if (state.DSM) {
1591                 output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1592             } else
1593                 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1594         } else
1595             output.print(task.getSafeSymbol()+"(");
1596         
1597         boolean printcomma=false;
1598         if (GENERATEPRECISEGC) {
1599             if (md!=null)
1600                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1601             else
1602                 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1603             printcomma=true;
1604         }
1605
1606         if (state.DSM&&lb.isAtomic()) {
1607             if (printcomma)
1608                 output.print(", ");
1609             output.print("transrecord_t * trans");
1610             printcomma=true;
1611         }
1612
1613         if (md!=null) {
1614             /* Method */
1615             for(int i=0;i<objectparams.numPrimitives();i++) {
1616                 TempDescriptor temp=objectparams.getPrimitive(i);
1617                 if (printcomma)
1618                     output.print(", ");
1619                 printcomma=true;
1620                 if (temp.getType().isClass()||temp.getType().isArray())
1621                     output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1622                 else
1623                     output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1624             }
1625             output.println(") {");
1626         } else if (!GENERATEPRECISEGC) {
1627             /* Imprecise Task */
1628             output.println("void * parameterarray[]) {");
1629             /* Unpack variables */
1630             for(int i=0;i<objectparams.numPrimitives();i++) {
1631                 TempDescriptor temp=objectparams.getPrimitive(i);
1632                 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
1633             }
1634             for(int i=0;i<fm.numTags();i++) {
1635                 TempDescriptor temp=fm.getTag(i);
1636                 int offset=i+objectparams.numPrimitives();
1637                 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
1638             }
1639
1640             if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
1641                 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
1642         } else output.println(") {");
1643     }
1644     
1645     public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
1646         output.println("/* FlatFlagActionNode */");
1647
1648
1649         /* Process tag changes */
1650         Relation tagsettable=new Relation();
1651         Relation tagcleartable=new Relation();
1652
1653         Iterator tagsit=ffan.getTempTagPairs(); 
1654         while (tagsit.hasNext()) {
1655             TempTagPair ttp=(TempTagPair) tagsit.next();
1656             TempDescriptor objtmp=ttp.getTemp();
1657             TagDescriptor tag=ttp.getTag();
1658             TempDescriptor tagtmp=ttp.getTagTemp();
1659             boolean tagstatus=ffan.getTagChange(ttp);
1660             if (tagstatus) {
1661                 tagsettable.put(objtmp, tagtmp);
1662             } else {
1663                 tagcleartable.put(objtmp, tagtmp);
1664             }
1665         }
1666
1667
1668         Hashtable flagandtable=new Hashtable();
1669         Hashtable flagortable=new Hashtable();
1670
1671         /* Process flag changes */
1672         Iterator flagsit=ffan.getTempFlagPairs();
1673         while(flagsit.hasNext()) {
1674             TempFlagPair tfp=(TempFlagPair)flagsit.next();
1675             TempDescriptor temp=tfp.getTemp();
1676             Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
1677             FlagDescriptor flag=tfp.getFlag();
1678             if (flag==null) {
1679                 //Newly allocate objects that don't set any flags case
1680                 if (flagortable.containsKey(temp)) {
1681                     throw new Error();
1682                 }
1683                 int mask=0;
1684                 flagortable.put(temp,new Integer(mask));
1685             } else {
1686                 int flagid=1<<((Integer)flagtable.get(flag)).intValue();
1687                 boolean flagstatus=ffan.getFlagChange(tfp);
1688                 if (flagstatus) {
1689                     int mask=0;
1690                     if (flagortable.containsKey(temp)) {
1691                         mask=((Integer)flagortable.get(temp)).intValue();
1692                     }
1693                     mask|=flagid;
1694                     flagortable.put(temp,new Integer(mask));
1695                 } else {
1696                     int mask=0xFFFFFFFF;
1697                     if (flagandtable.containsKey(temp)) {
1698                         mask=((Integer)flagandtable.get(temp)).intValue();
1699                     }
1700                     mask&=(0xFFFFFFFF^flagid);
1701                     flagandtable.put(temp,new Integer(mask));
1702                 }
1703             }
1704         }
1705
1706
1707         HashSet flagtagset=new HashSet();
1708         flagtagset.addAll(flagortable.keySet());
1709         flagtagset.addAll(flagandtable.keySet());
1710         flagtagset.addAll(tagsettable.keySet());
1711         flagtagset.addAll(tagcleartable.keySet());
1712
1713         Iterator ftit=flagtagset.iterator();
1714         while(ftit.hasNext()) {
1715             TempDescriptor temp=(TempDescriptor)ftit.next();
1716             
1717             
1718             Set tagtmps=tagcleartable.get(temp);
1719             if (tagtmps!=null) {
1720                 Iterator tagit=tagtmps.iterator();
1721                 while(tagit.hasNext()) {
1722                     TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1723                     if (GENERATEPRECISEGC) 
1724                         output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1725                     else
1726                         output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1727                 }
1728             }
1729
1730             tagtmps=tagsettable.get(temp);
1731             if (tagtmps!=null) {
1732                 Iterator tagit=tagtmps.iterator();
1733                 while(tagit.hasNext()) {
1734                     TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1735                     if (GENERATEPRECISEGC)
1736                         output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1737                     else
1738                         output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1739                 }
1740             }
1741
1742             int ormask=0;
1743             int andmask=0xFFFFFFF;
1744             
1745             if (flagortable.containsKey(temp))
1746                 ormask=((Integer)flagortable.get(temp)).intValue();
1747             if (flagandtable.containsKey(temp))
1748                 andmask=((Integer)flagandtable.get(temp)).intValue();
1749             if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
1750                 output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1751             } else {
1752                 output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1753             }
1754         }
1755     }
1756
1757      void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable optionaltaskdescriptors) {
1758          
1759          //GENERATE HEADERS
1760          headers.println("#include \"task.h\"\n\n");
1761          
1762          
1763          //STRUCT PREDICATEMEMBER
1764          headers.println("struct predicatemember{");
1765          headers.println("int type;");
1766          headers.println("int numdnfterms;");
1767          headers.println("int * flags;");
1768          headers.println("int numtags;");
1769          headers.println("int * tags;\n};\n\n");
1770
1771          //STRUCT EXITFLAGSTATE
1772          headers.println("struct exitflagstate{");
1773          headers.println("int numflags;");
1774          headers.println("int * flags;");
1775          /*
1776            headers.println("int numtags;");
1777            headers.println("int * tags;");
1778          */
1779          headers.println("\n};\n\n");
1780          
1781          //STRUCT EXITSTATES
1782          headers.println("struct exitstates{");
1783          headers.println("int numexitflagstates;");
1784          headers.println("struct exitflagstate * exitflagstatearray;\n};\n\n");
1785
1786          //STRUCT OPTIONALTASKDESCRIPTOR
1787          headers.println("struct optionaltaskdescriptor{");
1788          headers.println("struct taskdescriptor * task;");
1789          headers.println("int numpredicatemembers;");
1790          headers.println("struct predicatemember * predicatememberarray;");
1791          headers.println("int numexitstates;");
1792          headers.println("struct existates * exitstatesarray;\n};\n\n");
1793                  
1794          //STRUCT FSANALYSISWRAPPER
1795          headers.println("struct fsanalysiswrapper{");
1796          headers.println("int numflags;");
1797          headers.println("int * flags;");
1798          headers.println("int numtags;");
1799          headers.println("int * tags;");
1800          headers.println("int numoptionaltaskdescriptors;");
1801          headers.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray;\n};\n\n");
1802
1803          //STRUCT CLASSANALYSISWRAPPER
1804          headers.println("struct classanalyiswrapper{");
1805          headers.println("int type;");
1806          headers.println("int numfsanalysiswrappers;");
1807          headers.println("struct fsanalysiswrapper * fsanalysiswrapperarray;\n};\n\n");
1808
1809          Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1810          while(taskit.hasNext()) {
1811              TaskDescriptor td=(TaskDescriptor)taskit.next();
1812              headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
1813          }
1814          
1815                                                    
1816          
1817          //GENERATE STRUCTS
1818          output.println("#include \"optionalstruct.h\"\n\n");    
1819          HashSet processedcd = new HashSet();
1820         
1821
1822          Enumeration e = safeexecution.keys();
1823          while (e.hasMoreElements()) {
1824              
1825              //get the class
1826              ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
1827              Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
1828              
1829              //Generate the struct of optionals
1830              if((Hashtable)optionaltaskdescriptors.get(cdtemp)==null) System.out.println("Was in cd :"+cdtemp.getSymbol());
1831              Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
1832              if( !c_otd.isEmpty() ){
1833                  for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
1834                      OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
1835                      
1836                      //generate the int arrays for the predicate
1837                      Predicate predicate = otd.predicate;
1838                      int predicateindex = 0;
1839                      //iterate through the classes concerned by the predicate
1840                      Collection c_vard = predicate.vardescriptors.values();
1841                      for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
1842                          VarDescriptor vard = (VarDescriptor)vard_it.next();
1843                          TypeDescriptor typed = vard.getType();
1844                          
1845                          //generate for flags
1846                          HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
1847                          output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1848                          int numberterms=0;
1849                          if (fen_hashset!=null){
1850                              for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
1851                                  FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
1852                                  if (fen==null) {
1853                                      //output.println("0x0, 0x0 };");
1854                                      //numberterms+=1;
1855                                  }
1856                                  else {
1857                                      
1858                                      DNFFlag dflag=fen.getDNF();
1859                                      numberterms+=dflag.size();
1860                                      
1861                                      Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
1862                                      
1863                                      for(int j=0;j<dflag.size();j++) {
1864                                          if (j!=0)
1865                                              output.println(",");
1866                                          Vector term=dflag.get(j);
1867                                          int andmask=0;
1868                                          int checkmask=0;
1869                                          for(int k=0;k<term.size();k++) {
1870                                              DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
1871                                              FlagDescriptor fd=dfa.getFlag();
1872                                              boolean negated=dfa.getNegated();
1873                                              int flagid=1<<((Integer)flags.get(fd)).intValue();
1874                                              andmask|=flagid;
1875                                              if (!negated)
1876                                                  checkmask|=flagid;
1877                                          }
1878                                          output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
1879                                      }
1880                                  }
1881                              }
1882                          }
1883                          output.println("};\n");
1884                          
1885                          //generate for tags
1886                          TagExpressionList tagel = predicate.tags.get(vard.getSymbol()); 
1887                          output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1888                          //BUG...added next line to fix, test with any task program
1889                          int numtags = 0;
1890                          if (tagel!=null){
1891                              for(int j=0;j<tagel.numTags();j++) {
1892                                  if (j!=0)
1893                                      output.println(",");
1894                                  /* for each tag we need */
1895                                  /* which slot it is */
1896                                  /* what type it is */
1897                                  //TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(tagel.getName(j));
1898                                  TempDescriptor tmp=tagel.getTemp(j);
1899                                  //got rid of slot
1900                                  output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
1901                              }
1902                              numtags = tagel.numTags();
1903                          }
1904                          output.println("};");
1905                          
1906                          //store the result into a predicatemember struct
1907                          output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1908                          output.println("/*type*/"+typed.getClassDesc().getId()+",");
1909                          output.println("/* number of dnf terms */"+numberterms+",");
1910                          output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1911                          output.println("/* number of tag */"+numtags+",");
1912                          output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1913                          output.println("};\n");
1914                          predicateindex++;
1915                      }
1916                      
1917
1918                      //generate an array that stores the entire predicate
1919                      output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1920                      for( int j = 0; j<predicateindex; j++){
1921                          if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1922                          else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1923                      }
1924
1925                      //generate the struct for possible exitfses
1926                      HashSet<HashSet> exitfses = otd.exitfses;
1927                      int exitindex = 0;
1928                      int nbexit = exitfses.size();
1929                      int fsnumber;
1930                      
1931                      //iterate through possible exits
1932                      for(Iterator exitfseshash = exitfses.iterator(); exitfseshash.hasNext();){
1933                          HashSet temp_hashset = (HashSet)exitfseshash.next();
1934                          fsnumber = 0 ;
1935                          
1936                          //iterate through possible FSes corresponding to the exit
1937                          for(Iterator exfses = temp_hashset.iterator(); exfses.hasNext();){
1938                             FlagState fs = (FlagState)exfses.next();
1939                             fsnumber++;
1940                             output.println("int flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1941                             int counterflag = 0;
1942                             for(Iterator flags = fs.getFlags(); flags.hasNext();){
1943                                 FlagDescriptor flagd = (FlagDescriptor)flags.next();
1944                                 int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
1945                                 if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
1946                                 else  output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
1947                                 counterflag++;
1948                             } 
1949                             output.println("};\n");
1950                             //do the same for tags;
1951                             //maybe not needed because no tag changes tolerated.
1952
1953                             //store the information into a struct
1954                             output.println("struct exitflagstate exitflagstate"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1955                             output.println("/*number of flags*/"+counterflag+",");
1956                             output.println("flags"+fsnumber+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
1957                             output.println("};\n");
1958                          }
1959                          
1960                          //store fses corresponding to this exit into an array
1961                          output.println("struct exitflagstate * exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+" [] = {");
1962                          for( int j = 0; j<fsnumber; j++){
1963                              if( j != fsnumber-1)output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"'");
1964                              else output.println("&exitflagstate"+(j+1)+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1965                          }
1966                          
1967                          //store that information in a struct
1968                          output.println("struct exitstates exitstates"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1969                          output.println("/*number of exitflagstate*/"+fsnumber+",");
1970                          output.println("exitflagstatearray"+"_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
1971                          output.println("};\n");
1972
1973                          exitindex++;
1974                      }
1975                      
1976                      //store the information concerning all exits into an array
1977                      output.println("struct exitstates * exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1978                      for( int j = 0; j<nbexit; j++){
1979                          if( j != nbexit-1)output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1980                          else output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
1981                      }
1982                                      
1983                                      
1984                      //generate optionaltaskdescriptor that actually includes exit fses, predicate and the task concerned
1985                      output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
1986                      output.println("task_"+otd.td.getSafeSymbol()+",");
1987                      output.println("/*number of members */"+predicateindex+",");
1988                      output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
1989                      output.println("/*number of exit fses */"+nbexit+",");
1990                      output.println("exitstatearray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
1991                      output.println("};\n");
1992                  }      
1993              }
1994              else continue; // if there is no optionals, there is no need to build the rest of the struct 
1995              
1996              //get all the possible falgstates reachable by an object
1997              Hashtable hashtbtemp = safeexecution.get(cdtemp);
1998              Enumeration fses = hashtbtemp.keys();
1999              int fscounter = 0;
2000              while(fses.hasMoreElements()){
2001                  FlagState fs = (FlagState)fses.nextElement();
2002                  fscounter++;
2003                  
2004                  //get the set of OptionalTaskDescriptors corresponding
2005                  HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
2006                  //iterate through the OptionalTaskDescriptors and store the pointers to the optionals struct (see on top) into an array
2007                  
2008                  output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
2009                  for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
2010                      OptionalTaskDescriptor mm = (OptionalTaskDescriptor)mos.next();
2011                      if(!mos.hasNext()) output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
2012                      
2013                      else output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2014                  }
2015
2016                  //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
2017                  
2018                  output.println("int flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
2019                  for(Iterator flags = fs.getFlags(); flags.hasNext();){
2020                      FlagDescriptor flagd = (FlagDescriptor)flags.next();
2021                      int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
2022                      if( flags.hasNext() ) output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/,");
2023                      else  output.print("0x"+Integer.toHexString(flagid)+" /*"+Integer.toBinaryString(flagid)+"*/");
2024                      
2025                  }
2026                  //process tag information
2027                  
2028                  int tagcounter = 0;
2029                  //TagExpressionList tagel = fs.getTags(); 
2030                  //output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2031                  //BUG...added next line to fix, test with any task program
2032                  
2033                  //if (tagel!=null){
2034                  //    for(int j=0;j<tagel.numTags();j++) {
2035                  //      if (j!=0)
2036                  //          output.println(",");
2037                  //      TempDescriptor tmp=tagel.getTemp(j);
2038                  //      output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
2039                  //   }
2040                  //  numtags = tagel.numTags();
2041                  //}
2042                  //output.println("};");
2043                  
2044                  
2045                  //Store the result in fsanalysiswrapper
2046                  output.println("};\n");
2047                  output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
2048                  output.println("/* number of flags*/"+fs.numFlags()+",");
2049                  output.println("flags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
2050                  output.println("/* number of tags*/"+tagcounter+",");
2051                  output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
2052                  output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
2053                  output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
2054                  output.println("};\n");
2055                  
2056              }
2057
2058              //Build the array of fsanalysiswrappers
2059              output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
2060              for(int i = 0; i<fscounter; i++){
2061                  if(i==fscounter-1) output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+"};\n");
2062                          
2063                      else output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+",");
2064              }
2065
2066              //Build the classanalysiswrapper referring to the previous array
2067              output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
2068              output.println("/*type*/"+cdtemp.getId()+",");
2069              output.println("/* number of fsanalysiswrappers */"+fscounter+",");
2070              output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
2071              fscounter = 0;
2072              processedcd.add(cdtemp);
2073          }
2074
2075          //build an array containing every classes for which code has been build
2076          output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
2077          for(Iterator classit = processedcd.iterator(); classit.hasNext();){
2078              ClassDescriptor cdtemp=(ClassDescriptor)classit.next();
2079              if(!classit.hasNext()) output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+"};\n");
2080              else output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+",");
2081          }
2082          output.println("int numclasses = "+processedcd.size()+";");
2083          
2084      }
2085     
2086 }
2087          
2088
2089
2090
2091
2092