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