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