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