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