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