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