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