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