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