changes
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
1 package IR.Flat;
2 import IR.Tree.Modifiers;
3 import IR.Tree.FlagExpressionNode;
4 import IR.Tree.DNFFlag;
5 import IR.Tree.DNFFlagAtom;
6 import IR.Tree.TagExpressionList;
7 import IR.Tree.OffsetNode;
8 import IR.*;
9 import IR.Tree.JavaBuilder;
10
11 import java.util.*;
12 import java.io.*;
13
14 import Util.Relation;
15 import Analysis.TaskStateAnalysis.FlagState;
16 import Analysis.TaskStateAnalysis.FlagComparator;
17 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
18 import Analysis.TaskStateAnalysis.Predicate;
19 import Analysis.TaskStateAnalysis.SafetyAnalysis;
20 import Analysis.TaskStateAnalysis.TaskIndex;
21 import Analysis.CallGraph.CallGraph;
22 import Analysis.Loops.GlobalFieldType;
23 import Util.CodePrinter;
24
25 public class BuildCode {
26   State state;
27   Hashtable temptovar;
28   Hashtable paramstable;
29   Hashtable tempstable;
30   Hashtable fieldorder;
31   Hashtable flagorder;
32   int tag=0;
33   String localsprefix="___locals___";
34   String localsprefixaddr="&"+localsprefix;
35   String localsprefixderef=localsprefix+".";
36   String fcrevert="___fcrevert___";
37   String paramsprefix="___params___";
38   String nextobjstr="___nextobject___";
39   String localcopystr="___localcopy___";
40   public static boolean GENERATEPRECISEGC=false;
41   public static String PREFIX="";
42   public static String arraytype="ArrayObject";
43   public static int flagcount = 0;
44   Virtual virtualcalls;
45   public TypeUtil typeutil;
46   protected int maxtaskparams=0;
47   protected int maxcount=0;
48   ClassDescriptor[] cdarray;
49   ClassDescriptor[] ifarray;
50   TypeDescriptor[] arraytable;
51   SafetyAnalysis sa;
52   CallGraph callgraph;
53   Hashtable<String, ClassDescriptor> printedfieldstbl;
54   int globaldefscount=0;
55   boolean mgcstaticinit = false;
56   JavaBuilder javabuilder;
57   String strObjType;
58
59
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)))
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) || (this.state.MULTICOREGC))
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) || (this.state.MULTICOREGC)))
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) || (this.state.MULTICOREGC)) {
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) {
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 (this.state.MULTICOREGC) {
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) || (this.state.MULTICOREGC)) {
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         || this.state.MULTICOREGC) {
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 (this.state.MULTICOREGC) {
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       // this node is just for generating a reach graph
2382       // in disjointness analysis at a particular program point
2383       break;
2384
2385     case FKind.FlatExit:
2386       output.println("/* exit */");
2387       break;
2388
2389     case FKind.FlatBackEdge:
2390       generateFlatBackEdge(fm, (FlatBackEdge)fn, output);
2391       break;
2392
2393     case FKind.FlatCheckNode:
2394       generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
2395       break;
2396
2397     case FKind.FlatFlagActionNode:
2398       generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output);
2399       break;
2400
2401     case FKind.FlatPrefetchNode:
2402       generateFlatPrefetchNode(fm, (FlatPrefetchNode) fn, output);
2403       break;
2404
2405     case FKind.FlatOffsetNode:
2406       generateFlatOffsetNode(fm, (FlatOffsetNode)fn, output);
2407       break;
2408
2409     default:
2410       throw new Error();
2411     }
2412
2413     additionalCodePostNode(fm, fn, output);
2414     for(BuildCodeExtension bcx: extensions) {
2415       bcx.additionalCodePostNode(fm, fn, output);
2416     }
2417
2418   }
2419
2420   public void generateFlatBackEdge(FlatMethod fm, FlatBackEdge fn, PrintWriter output) {
2421     if (((state.OOOJAVA||state.THREAD)&&GENERATEPRECISEGC)
2422         || (this.state.MULTICOREGC)) {
2423       if(this.state.MULTICOREGC) {
2424         output.println("GCCHECK("+localsprefixaddr+");");
2425       } else {
2426         output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
2427       }
2428     } else
2429       output.println("/* nop */");
2430   }
2431
2432   public void generateFlatOffsetNode(FlatMethod fm, FlatOffsetNode fofn, PrintWriter output) {
2433     output.println("/* FlatOffsetNode */");
2434     FieldDescriptor fd=fofn.getField();
2435     if(!fd.isStatic()) {
2436       output.println(generateTemp(fm, fofn.getDst())+ " = (short)(int) (&((struct "+fofn.getClassType().getSafeSymbol() +" *)0)->"+
2437                      fd.getSafeSymbol()+");");
2438     }
2439     output.println("/* offset */");
2440   }
2441
2442   public void generateFlatPrefetchNode(FlatMethod fm, FlatPrefetchNode fpn, PrintWriter output) {
2443   }
2444
2445   public void generateFlatGlobalConvNode(FlatMethod fm, FlatGlobalConvNode fgcn, PrintWriter output) {
2446   }
2447
2448   public void generateFlatInstanceOfNode(FlatMethod fm,  FlatInstanceOfNode fion, PrintWriter output) {
2449     int type;
2450     int otype;
2451     if (fion.getType().isArray()) {
2452       type=state.getArrayNumber(fion.getType())+state.numClasses();
2453     } else if (fion.getType().getClassDesc().isInterface()) {
2454       type=fion.getType().getClassDesc().getId()+state.numClasses()+state.numArrays();
2455     } else {
2456       type=fion.getType().getClassDesc().getId();
2457     }
2458     if (fion.getSrc().getType().isArray()) {
2459       otype=state.getArrayNumber(fion.getSrc().getType())+state.numClasses();
2460     } else if (fion.getSrc().getType().getClassDesc().isInterface()) {
2461       otype=fion.getSrc().getType().getClassDesc().getId()+state.numClasses()+state.numArrays();
2462     } else {
2463       otype=fion.getSrc().getType().getClassDesc().getId();
2464     }
2465
2466     if (fion.getType().getSymbol().equals(TypeUtil.ObjectClass))
2467       output.println(generateTemp(fm, fion.getDst())+"=(" + generateTemp(fm,fion.getSrc()) + "!= NULL);");
2468     else {
2469       output.println(generateTemp(fm, fion.getDst())+"=instanceof("+generateTemp(fm,fion.getSrc())+","+type+");");
2470     }
2471   }
2472
2473   public void generateFlatAtomicEnterNode(FlatMethod fm, FlatAtomicEnterNode faen, PrintWriter output) {
2474   }
2475
2476   public void generateFlatAtomicExitNode(FlatMethod fm,  FlatAtomicExitNode faen, PrintWriter output) {
2477   }
2478
2479   public void generateFlatSESEEnterNode(FlatMethod fm,
2480                                         FlatSESEEnterNode fsen,
2481                                         PrintWriter output) {
2482     // if OOOJAVA flag is off, okay that SESE nodes are in IR graph,
2483     // just skip over them and code generates exactly the same
2484   }
2485
2486   public void generateFlatSESEExitNode(FlatMethod fm,
2487                                        FlatSESEExitNode fsexn,
2488                                        PrintWriter output) {
2489     // if OOOJAVA flag is off, okay that SESE nodes are in IR graph,
2490     // just skip over them and code generates exactly the same
2491   }
2492
2493   public void generateFlatWriteDynamicVarNode(FlatMethod fm,
2494                                               FlatWriteDynamicVarNode fwdvn,
2495                                               PrintWriter output) {
2496   }
2497
2498
2499   protected void generateFlatCheckNode(FlatMethod fm,  FlatCheckNode fcn, PrintWriter output) {
2500     if (state.CONSCHECK) {
2501       String specname=fcn.getSpec();
2502       String varname="repairstate___";
2503       output.println("{");
2504       output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
2505
2506       TempDescriptor[] temps=fcn.getTemps();
2507       String[] vars=fcn.getVars();
2508       for(int i=0; i<temps.length; i++) {
2509         output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i])+";");
2510       }
2511
2512       output.println("if (doanalysis"+specname+"("+varname+")) {");
2513       output.println("free"+specname+"_state("+varname+");");
2514       output.println("} else {");
2515       output.println("/* Bad invariant */");
2516       output.println("free"+specname+"_state("+varname+");");
2517       output.println("abort_task();");
2518       output.println("}");
2519       output.println("}");
2520     }
2521   }
2522
2523   protected void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
2524     MethodDescriptor md=fc.getMethod();
2525     ParamsObject objectparams=(ParamsObject)paramstable.get(md);
2526
2527     ClassDescriptor cn=md.getClassDesc();
2528     String mdstring = md.getSafeMethodDescriptor();
2529     if(mgcstaticinit && !md.isStaticBlock() && !md.getModifiers().isNative()) {
2530       mdstring += "staticinit";
2531     }
2532
2533     // if the called method is a static block or a static method or a constructor
2534     // need to check if it can be invoked inside some static block
2535     if((md.isStatic() || md.isStaticBlock() || md.isConstructor()) &&
2536        ((fm.getMethod() != null) && ((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())))) {
2537       if(!md.isInvokedByStatic()) {
2538         System.err.println("Error: a method that is invoked inside a static block is not tagged!");
2539       }
2540       // is a static block or is invoked in some static block
2541       ClassDescriptor cd = fm.getMethod().getClassDesc();
2542       if(cd != cn && mgcstaticinit && callgraph.isInit(cn)) {
2543         // generate static init check code if it has not done static init in main()
2544         if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
2545           // need to check if the class' static fields have been initialized and/or
2546           // its static blocks have been executed
2547           output.println("if(global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {");
2548           if(cn.getNumStaticBlocks() != 0) {
2549             MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks");
2550             if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2551               output.print("       struct "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2552               output.println("0, NULL};");
2553               output.println("     "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);");
2554             } else {
2555               output.println("  "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
2556             }
2557           } else {
2558             output.println("  global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;");
2559           }
2560           output.println("}");
2561         }
2562       }
2563     }
2564     if((md.getSymbol().equals("MonitorEnter") || md.getSymbol().equals("MonitorExit")) && fc.getThis().getSymbol().equals("classobj")) {
2565       output.println("{");
2566       if(md.getSymbol().equals("MonitorEnter") && state.OBJECTLOCKDEBUG) {
2567         output.println("int monitorenterline = __LINE__;");
2568       }
2569       // call MonitorEnter/MonitorExit on a class obj
2570       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2571         output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2572         output.println("1," + localsprefixaddr + ", ((void **)(((char *) &(global_defs_p->classobjs->___length___))+sizeof(int)))[" + fc.getThis().getType().getClassDesc().getId() + "]};");
2573         if(md.getSymbol().equals("MonitorEnter") && state.OBJECTLOCKDEBUG) {
2574           output.println("     "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__, monitorenterline);");
2575         } else {
2576           output.println("     "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
2577         }
2578       } else {
2579         output.println("       " + cn.getSafeSymbol()+md.getSafeSymbol()+"_"
2580                        + md.getSafeMethodDescriptor() + "((struct ___Object___*)(((void **)(((char *) &(global_defs_p->classobjs->___length___))+sizeof(int)))["
2581                        + fc.getThis().getType().getClassDesc().getId() + "]));");
2582       }
2583       output.println("}");
2584       return;
2585     }
2586
2587     output.println("{");
2588     if(md.getSymbol().equals("MonitorEnter")) {
2589       output.println("int monitorenterline = __LINE__;");
2590     }
2591     if (GENERATEPRECISEGC || state.MULTICOREGC) {
2592       output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"_params __parameterlist__={");
2593       output.print(objectparams.numPointers());
2594       output.print(", "+localsprefixaddr);
2595       if (md.getThis()!=null) {
2596         output.print(", ");
2597         output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis()));
2598       }
2599       if (fc.getThis()!=null&&md.getThis()==null) {
2600         System.out.println("WARNING!!!!!!!!!!!!");
2601         System.out.println("Source code calls static method "+md+" on an object in "+fm.getMethod()+"!");
2602       }
2603
2604       for(int i=0; i<fc.numArgs(); i++) {
2605         Descriptor var=md.getParameter(i);
2606         TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2607         if (objectparams.isParamPtr(paramtemp)) {
2608           TempDescriptor targ=fc.getArg(i);
2609           output.print(", ");
2610           TypeDescriptor td=md.getParamType(i);
2611           if (td.isTag())
2612             output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
2613           else
2614             output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
2615         }
2616       }
2617       output.println("};");
2618     }
2619     output.print("       ");
2620
2621
2622     if (fc.getReturnTemp()!=null)
2623       output.print(generateTemp(fm,fc.getReturnTemp())+"=");
2624
2625     /* Do we need to do virtual dispatch? */
2626
2627     if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)||fc.getSuper()) {
2628       //no
2629       output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring);
2630     } else {
2631       //yes
2632       output.print("((");
2633       if (md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) {
2634         output.print("int ");
2635       } else if (md.getReturnType().isClass()||md.getReturnType().isArray())
2636         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
2637       else
2638         output.print(md.getReturnType().getSafeSymbol()+" ");
2639       output.print("(*)(");
2640
2641       boolean printcomma=false;
2642       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2643         output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"_params * ");
2644         printcomma=true;
2645       }
2646
2647       for(int i=0; i<objectparams.numPrimitives(); i++) {
2648         TempDescriptor temp=objectparams.getPrimitive(i);
2649         if (printcomma)
2650           output.print(", ");
2651         printcomma=true;
2652         if (temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
2653           output.print("int ");
2654         } else if (temp.getType().isClass()||temp.getType().isArray())
2655           output.print("struct " + temp.getType().getSafeSymbol()+" * ");
2656         else
2657           output.print(temp.getType().getSafeSymbol());
2658       }
2659
2660       if(md.getSymbol().equals("MonitorEnter") && state.OBJECTLOCKDEBUG) {
2661         output.print(", int");
2662       }
2663       output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
2664     }
2665
2666     output.print("(");
2667     boolean needcomma=false;
2668     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2669       output.print("&__parameterlist__");
2670       needcomma=true;
2671     }
2672
2673     if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
2674       if (fc.getThis()!=null) {
2675         TypeDescriptor ptd=null;
2676         if(md.getThis() != null) {
2677           ptd = md.getThis().getType();
2678         } else {
2679           ptd = fc.getThis().getType();
2680         }
2681         if (needcomma)
2682           output.print(",");
2683         if(ptd.isClass() && ptd.getClassDesc().isEnum()) {
2684           // do nothing
2685         } else if (ptd.isClass()&&!ptd.isArray())
2686           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2687         output.print(generateTemp(fm,fc.getThis()));
2688         needcomma=true;
2689       }
2690     }
2691
2692     for(int i=0; i<fc.numArgs(); i++) {
2693       Descriptor var=md.getParameter(i);
2694       TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2695       if (objectparams.isParamPrim(paramtemp)) {
2696         TempDescriptor targ=fc.getArg(i);
2697         if (needcomma)
2698           output.print(", ");
2699
2700         TypeDescriptor ptd=md.getParamType(i);
2701         if (ptd.isClass() && ptd.getClassDesc().isEnum()) {
2702           // do nothing
2703         } else if (ptd.isClass()&&!ptd.isArray())
2704           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2705         output.print(generateTemp(fm, targ));
2706         needcomma=true;
2707       }
2708     }
2709     if(md.getSymbol().equals("MonitorEnter") && state.OBJECTLOCKDEBUG) {
2710       output.println(", monitorenterline);");
2711     } else {
2712       output.println(");");
2713     }
2714     output.println("   }");
2715   }
2716
2717   protected boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
2718     if(thiscd.isInterface()) {
2719       // for interfaces, always need virtual dispatch
2720       return false;
2721     } else {
2722       Set subclasses=typeutil.getSubClasses(thiscd);
2723       if (subclasses==null)
2724         return true;
2725       for(Iterator classit=subclasses.iterator(); classit.hasNext(); ) {
2726         ClassDescriptor cd=(ClassDescriptor)classit.next();
2727         Set possiblematches=cd.getMethodTable().getSetFromSameScope(md.getSymbol());
2728         for(Iterator matchit=possiblematches.iterator(); matchit.hasNext(); ) {
2729           MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
2730           if (md.matches(matchmd))
2731             return false;
2732         }
2733       }
2734     }
2735     return true;
2736   }
2737
2738   protected void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
2739
2740     if(ffn.getField().isStatic()) {
2741       // static field
2742       if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
2743         // is a static block or is invoked in some static block
2744         ClassDescriptor cd = fm.getMethod().getClassDesc();
2745         ClassDescriptor cn = ffn.getSrc().getType().getClassDesc();
2746         if(cd != cn && mgcstaticinit && callgraph.isInit(cn)) {
2747           // generate the static init check code if has not done the static init in main()
2748           if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
2749             // need to check if the class' static fields have been initialized and/or
2750             // its static blocks have been executed
2751             output.println("if(global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {");
2752             if(cn.getNumStaticBlocks() != 0) {
2753               MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks");
2754               if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2755                 output.print("       struct "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2756                 output.println("0, NULL};");
2757                 output.println("     "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);");
2758               } else {
2759                 output.println("  "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
2760               }
2761             } else {
2762               output.println("  global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;");
2763             }
2764             output.println("}");
2765           }
2766         }
2767       }
2768       // redirect to the global_defs_p structure
2769       if (ffn.getField().getType().isPtr())
2770         output.println(generateTemp(fm, ffn.getDst())+"=global_defs_p->"+ffn.getField().getSafeSymbol()+";");
2771       else
2772         output.println(generateTemp(fm, ffn.getDst())+"=global_defsprim_p->"+ffn.getField().getSafeSymbol()+";");
2773     } else if (ffn.getField().isEnum()) {
2774       // an Enum value, directly replace the field access as int
2775       output.println(generateTemp(fm, ffn.getDst()) + "=" + ffn.getField().enumValue() + ";");
2776     } else {
2777       if( state.CAPTURE_NULL_DEREFERENCES ) {
2778         output.println("#ifdef CAPTURE_NULL_DEREFERENCES");
2779         output.println("if (" + generateTemp(fm,ffn.getSrc()) + " == NULL) {");
2780         output.println("printf(\" NULL ptr error: %s, %s, %d \\n\", __FILE__, __func__, __LINE__);");
2781         if(state.MULTICOREGC) {
2782           output.println("failednullptr(&___locals___);");
2783         } else {
2784           output.println("failednullptr(NULL);");
2785         }
2786         output.println("}");
2787         output.println("#endif //CAPTURE_NULL_DEREFERENCES");
2788       }
2789       output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
2790     }
2791   }
2792
2793
2794   protected void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) {
2795     if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
2796       throw new Error("Can't set array length");
2797     if (state.FASTCHECK) {
2798       String dst=generateTemp(fm, fsfn.getDst());
2799       output.println("if(!"+dst+"->"+localcopystr+") {");
2800       /* Link object into list */
2801       if (GENERATEPRECISEGC || this.state.MULTICOREGC)
2802         output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
2803       else
2804         output.println("COPY_OBJ("+dst+");");
2805       output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2806       output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2807       output.println("}");
2808     }
2809
2810     if(fsfn.getField().isStatic()) {
2811       // static field
2812       if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
2813         // is a static block or is invoked in some static block
2814         ClassDescriptor cd = fm.getMethod().getClassDesc();
2815         ClassDescriptor cn = fsfn.getDst().getType().getClassDesc();
2816         if(cd != cn && mgcstaticinit && callgraph.isInit(cn)) {
2817           // generate static init check code if has not done the static init in main()
2818           if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
2819             // need to check if the class' static fields have been initialized and/or
2820             // its static blocks have been executed
2821             output.println("if(global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {");
2822             if(cn.getNumStaticBlocks() != 0) {
2823               MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks");
2824               if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2825                 output.print("       struct "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2826                 output.println("0, NULL};");
2827                 output.println("     "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"(& __parameterlist__);");
2828               } else {
2829                 output.println("  "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
2830               }
2831             } else {
2832               output.println("  global_defsprim_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;");
2833             }
2834             output.println("}");
2835           }
2836         }
2837       }
2838       // redirect to the global_defs_p structure
2839       if (fsfn.getField().getType().isPtr()) {
2840         if (fsfn.getField().getType()!=fsfn.getSrc().getType())
2841           output.println("global_defs_p->" +
2842                          fsfn.getField().getSafeSymbol()+"=(struct "+ fsfn.getField().getType().getSafeSymbol()+" *)"+generateTemp(fm,fsfn.getSrc())+";");
2843         else
2844           output.println("global_defs_p->" +
2845                          fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
2846       } else
2847         output.println("global_defsprim_p->" +
2848                        fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
2849     } else {
2850
2851       if( state.CAPTURE_NULL_DEREFERENCES ) {
2852         output.println("#ifdef CAPTURE_NULL_DEREFERENCES");
2853         output.println("if (" + generateTemp(fm,fsfn.getDst()) + " == NULL) {");
2854         output.println("printf(\" NULL ptr error: %s, %s, %d \\n\", __FILE__, __func__, __LINE__);");
2855         if(state.MULTICOREGC) {
2856           output.println("failednullptr(&___locals___);");
2857         } else {
2858           output.println("failednullptr(NULL);");
2859         }
2860         output.println("}");
2861         output.println("#endif //CAPTURE_NULL_DEREFERENCES");
2862       }
2863
2864       if (fsfn.getSrc().getType().isPtr()&&fsfn.getSrc().getType()!=fsfn.getField().getType())
2865         output.println(generateTemp(fm, fsfn.getDst())+"->"+
2866                        fsfn.getField().getSafeSymbol()+"=(struct "+ fsfn.getField().getType().getSafeSymbol()+"*)"+generateTemp(fm,fsfn.getSrc())+";");
2867       else
2868         output.println(generateTemp(fm, fsfn.getDst())+"->"+
2869                        fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
2870     }
2871   }
2872
2873
2874   protected void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
2875     TypeDescriptor elementtype=fen.getSrc().getType().dereference();
2876     String type="";
2877
2878     if (elementtype.isClass() && elementtype.getClassDesc().isEnum()) {
2879       type="int ";
2880     } else if (elementtype.isArray()||elementtype.isClass())
2881       type="void *";
2882     else
2883       type=elementtype.getSafeSymbol()+" ";
2884
2885     if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) {
2886       output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fen.getIndex())+") >= "+generateTemp(fm,fen.getSrc()) + "->___length___))");
2887       output.println("failedboundschk(__LINE__, " +generateTemp(fm, fen.getIndex()) +", "+ generateTemp(fm, fen.getSrc()) + ");");
2888     }
2889     output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
2890     if (fen.getDst().getType().isPtr())
2891       ;
2892   }
2893
2894   protected void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
2895     //TODO: need dynamic check to make sure this assignment is actually legal
2896     //Because Object[] could actually be something more specific...ie. Integer[]
2897
2898     TypeDescriptor elementtype=fsen.getDst().getType().dereference();
2899     String type="";
2900
2901     if (elementtype.isClass() && elementtype.getClassDesc().isEnum()) {
2902       type="int ";
2903     } else if (elementtype.isArray()||elementtype.isClass() || (elementtype.isNull()))
2904       type="void *";
2905     else
2906       type=elementtype.getSafeSymbol()+" ";
2907
2908     if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) {
2909       output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fsen.getIndex())+") >= "+generateTemp(fm,fsen.getDst()) + "->___length___))");
2910       output.println("failedboundschk(__LINE__, " +generateTemp(fm, fsen.getIndex()) +", "+ generateTemp(fm, fsen.getDst()) + ");");
2911     }
2912     if (state.FASTCHECK) {
2913       String dst=generateTemp(fm, fsen.getDst());
2914       output.println("if(!"+dst+"->"+localcopystr+") {");
2915       /* Link object into list */
2916       if (GENERATEPRECISEGC || this.state.MULTICOREGC)
2917         output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
2918       else
2919         output.println("COPY_OBJ("+dst+");");
2920       output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2921       output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2922       output.println("}");
2923     }
2924     output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
2925   }
2926
2927
2928   protected void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
2929     String dst=generateTemp(fm,fn.getDst());
2930
2931     if (fn.getType().isArray()) {
2932       int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
2933       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2934         output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");");
2935       } else {
2936         output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
2937       }
2938     } else {
2939       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2940         output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
2941       } else {
2942         output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
2943       }
2944     }
2945     if (state.FASTCHECK) {
2946       output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
2947       output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2948       output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2949     }
2950     for(BuildCodeExtension bcx: extensions) {
2951       bcx.additionalCodeNewObject(output, dst, fn);
2952     }
2953   }
2954
2955   protected void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) {
2956     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
2957       output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+localsprefixaddr+", "+state.getTagId(fn.getType())+");");
2958     } else {
2959       output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");");
2960     }
2961   }
2962
2963   protected void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
2964     if (fon.getRight()!=null) {
2965       if (fon.getOp().getOp()==Operation.URIGHTSHIFT) {
2966         if (fon.getLeft().getType().isLong())
2967           output.println(generateTemp(fm, fon.getDest())+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft())+")>>"+generateTemp(fm,fon.getRight())+";");
2968         else
2969           output.println(generateTemp(fm, fon.getDest())+" = ((unsigned int)"+generateTemp(fm, fon.getLeft())+")>>"+generateTemp(fm,fon.getRight())+";");
2970
2971       } else {
2972         if (fon.getLeft().getType().isPtr()&&fon.getLeft().getType()!=fon.getRight().getType()&&!fon.getRight().getType().isNull())
2973           output.println(generateTemp(fm, fon.getDest())+" = (struct "+fon.getRight().getType().getSafeSymbol()+"*)"+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
2974         else
2975           output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
2976       }
2977     } else if (fon.getOp().getOp()==Operation.ASSIGN)
2978       if (fon.getDest().getType().isPtr()&&fon.getDest().getType()!=fon.getLeft().getType())
2979         output.println(generateTemp(fm, fon.getDest())+" = (struct "+fon.getDest().getType().getSafeSymbol()+"*)"+generateTemp(fm, fon.getLeft())+";");
2980       else
2981         output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
2982     else if (fon.getOp().getOp()==Operation.UNARYPLUS)
2983       output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
2984     else if (fon.getOp().getOp()==Operation.UNARYMINUS)
2985       output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
2986     else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
2987       output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";");
2988     else if (fon.getOp().getOp()==Operation.COMP)
2989       output.println(generateTemp(fm, fon.getDest())+" = ~"+generateTemp(fm, fon.getLeft())+";");
2990     else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
2991       output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+"->fses==NULL;");
2992     } else
2993       output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
2994   }
2995
2996   protected void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
2997     /* TODO: Do type check here */
2998     if (fcn.getType().isArray()) {
2999       output.println(generateTemp(fm,fcn.getDst())+"=(struct ArrayObject *)"+generateTemp(fm,fcn.getSrc())+";");
3000     } else if (fcn.getType().isClass() && fcn.getType().getClassDesc().isEnum()) {
3001       output.println(generateTemp(fm,fcn.getDst())+"=(int)"+generateTemp(fm,fcn.getSrc())+";");
3002     } else if (fcn.getType().isClass())
3003       output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";");
3004     else
3005       output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
3006   }
3007
3008   int flncount=0;
3009
3010   protected void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
3011     if (fln.getValue()==null)
3012       output.println(generateTemp(fm, fln.getDst())+"=0;");
3013     else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
3014       String str=(String)fln.getValue();
3015       output.println("{");
3016       output.print("short str"+flncount+"[]={");
3017       for(int i=0; i<str.length(); i++) {
3018         if (i!=0)
3019           output.print(", ");
3020         output.print(((int)str.charAt(i)));
3021       }
3022       output.println("};");
3023       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3024         output.println(generateTemp(fm, fln.getDst())+"=NewStringShort("+localsprefixaddr+", str"+flncount+", "+((String)fln.getValue()).length()+");");
3025       } else {
3026         output.println(generateTemp(fm, fln.getDst())+"=NewStringShort(str"+flncount+" ,"+((String)fln.getValue()).length()+");");
3027       }
3028       
3029       for(BuildCodeExtension bcx: extensions) {
3030         bcx.additionalCodeNewStringLiteral(output, generateTemp(fm, fln.getDst()));
3031       }      
3032
3033       output.println("}");
3034       flncount++;
3035     } else if (fln.getType().isBoolean()) {
3036       if (((Boolean)fln.getValue()).booleanValue())
3037         output.println(generateTemp(fm, fln.getDst())+"=1;");
3038       else
3039         output.println(generateTemp(fm, fln.getDst())+"=0;");
3040     } else if (fln.getType().isChar()) {
3041       int val=(int)(((Character)fln.getValue()).charValue());
3042       output.println(generateTemp(fm, fln.getDst())+"="+val+";");
3043     } else if (fln.getType().isLong()) {
3044       output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+"LL;");
3045     } else
3046       output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
3047   }
3048
3049   protected void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
3050     if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) {
3051       // a static block, check if it has been executed
3052       output.println("  global_defsprim_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;");
3053       output.println("");
3054     }
3055
3056     if (frn.getReturnTemp()!=null) {
3057       if (frn.getReturnTemp().getType().isPtr())
3058         output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp())+";");
3059       else
3060         output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
3061     } else {
3062       output.println("return;");
3063     }
3064   }
3065
3066   protected void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
3067     output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
3068   }
3069
3070   /** This method generates header information for the method or
3071    * task referenced by the Descriptor des. */
3072   protected void generateHeader(FlatMethod fm, Descriptor des, PrintWriter output) {
3073     generateHeader(fm, des, output, false);
3074   }
3075
3076   protected void generateHeader(FlatMethod fm, Descriptor des, PrintWriter output, boolean addSESErecord) {
3077     /* Print header */
3078     ParamsObject objectparams=(ParamsObject)paramstable.get(des);
3079     MethodDescriptor md=null;
3080     TaskDescriptor task=null;
3081     if (des instanceof MethodDescriptor)
3082       md=(MethodDescriptor) des;
3083     else
3084       task=(TaskDescriptor) des;
3085     String mdstring = md != null?md.getSafeMethodDescriptor():null;
3086
3087     ClassDescriptor cn=md!=null?md.getClassDesc():null;
3088
3089     if (md!=null&&md.getReturnType()!=null) {
3090       if (md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) {
3091         output.print("int ");
3092       } else if (md.getReturnType().isClass()||md.getReturnType().isArray())
3093         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
3094       else
3095         output.print(md.getReturnType().getSafeSymbol()+" ");
3096     } else
3097       //catch the constructor case
3098       output.print("void ");
3099     if (md!=null) {
3100       if(mgcstaticinit && !md.isStaticBlock() && !md.getModifiers().isNative()) {
3101         mdstring += "staticinit";
3102       }
3103       output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"(");
3104     } else
3105       output.print(task.getSafeSymbol()+"(");
3106
3107     boolean printcomma=false;
3108     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3109       if (md!=null) {
3110         output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+mdstring+"_params * "+paramsprefix);
3111       } else
3112         output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
3113       printcomma=true;
3114     }
3115
3116     if (md!=null) {
3117       /* Method */
3118       for(int i=0; i<objectparams.numPrimitives(); i++) {
3119         TempDescriptor temp=objectparams.getPrimitive(i);
3120         if (printcomma)
3121           output.print(", ");
3122         printcomma=true;
3123         if(temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
3124           output.print("int " + temp.getSafeSymbol());
3125         } else if (temp.getType().isClass()||temp.getType().isArray())
3126           output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
3127         else
3128           output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
3129       }
3130       output.println(") {");
3131     } else if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
3132       /* Imprecise Task */
3133       output.println("void * parameterarray[]) {");
3134       /* Unpack variables */
3135       for(int i=0; i<objectparams.numPrimitives(); i++) {
3136         TempDescriptor temp=objectparams.getPrimitive(i);
3137         if(temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
3138           output.print("int " + temp.getSafeSymbol() + "=parameterarray["+i+"];");
3139         } else {
3140           output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
3141         }
3142       }
3143       for(int i=0; i<fm.numTags(); i++) {
3144         TempDescriptor temp=fm.getTag(i);
3145         int offset=i+objectparams.numPrimitives();
3146         output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
3147       }
3148
3149       if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
3150         maxtaskparams=objectparams.numPrimitives()+fm.numTags();
3151     } else output.println(") {");
3152   }
3153
3154   public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
3155     output.println("/* FlatFlagActionNode */");
3156
3157
3158     /* Process tag changes */
3159     Relation tagsettable=new Relation();
3160     Relation tagcleartable=new Relation();
3161
3162     Iterator tagsit=ffan.getTempTagPairs();
3163     while (tagsit.hasNext()) {
3164       TempTagPair ttp=(TempTagPair) tagsit.next();
3165       TempDescriptor objtmp=ttp.getTemp();
3166       TagDescriptor tag=ttp.getTag();
3167       TempDescriptor tagtmp=ttp.getTagTemp();
3168       boolean tagstatus=ffan.getTagChange(ttp);
3169       if (tagstatus) {
3170         tagsettable.put(objtmp, tagtmp);
3171       } else {
3172         tagcleartable.put(objtmp, tagtmp);
3173       }
3174     }
3175
3176
3177     Hashtable flagandtable=new Hashtable();
3178     Hashtable flagortable=new Hashtable();
3179
3180     /* Process flag changes */
3181     Iterator flagsit=ffan.getTempFlagPairs();
3182     while(flagsit.hasNext()) {
3183       TempFlagPair tfp=(TempFlagPair)flagsit.next();
3184       TempDescriptor temp=tfp.getTemp();
3185       Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
3186       FlagDescriptor flag=tfp.getFlag();
3187       if (flag==null) {
3188         //Newly allocate objects that don't set any flags case
3189         if (flagortable.containsKey(temp)) {
3190           throw new Error();
3191         }
3192         int mask=0;
3193         flagortable.put(temp,new Integer(mask));
3194       } else {
3195         int flagid=1<<((Integer)flagtable.get(flag)).intValue();
3196         boolean flagstatus=ffan.getFlagChange(tfp);
3197         if (flagstatus) {
3198           int mask=0;
3199           if (flagortable.containsKey(temp)) {
3200             mask=((Integer)flagortable.get(temp)).intValue();
3201           }
3202           mask|=flagid;
3203           flagortable.put(temp,new Integer(mask));
3204         } else {
3205           int mask=0xFFFFFFFF;
3206           if (flagandtable.containsKey(temp)) {
3207             mask=((Integer)flagandtable.get(temp)).intValue();
3208           }
3209           mask&=(0xFFFFFFFF^flagid);
3210           flagandtable.put(temp,new Integer(mask));
3211         }
3212       }
3213     }
3214
3215
3216     HashSet flagtagset=new HashSet();
3217     flagtagset.addAll(flagortable.keySet());
3218     flagtagset.addAll(flagandtable.keySet());
3219     flagtagset.addAll(tagsettable.keySet());
3220     flagtagset.addAll(tagcleartable.keySet());
3221
3222     Iterator ftit=flagtagset.iterator();
3223     while(ftit.hasNext()) {
3224       TempDescriptor temp=(TempDescriptor)ftit.next();
3225
3226
3227       Set tagtmps=tagcleartable.get(temp);
3228       if (tagtmps!=null) {
3229         Iterator tagit=tagtmps.iterator();
3230         while(tagit.hasNext()) {
3231           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
3232           if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
3233             output.println("tagclear("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
3234           else
3235             output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
3236         }
3237       }
3238
3239       tagtmps=tagsettable.get(temp);
3240       if (tagtmps!=null) {
3241         Iterator tagit=tagtmps.iterator();
3242         while(tagit.hasNext()) {
3243           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
3244           if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
3245             output.println("tagset("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
3246           else
3247             output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
3248         }
3249       }
3250
3251       int ormask=0;
3252       int andmask=0xFFFFFFF;
3253
3254       if (flagortable.containsKey(temp))
3255         ormask=((Integer)flagortable.get(temp)).intValue();
3256       if (flagandtable.containsKey(temp))
3257         andmask=((Integer)flagandtable.get(temp)).intValue();
3258       generateFlagOrAnd(ffan, fm, temp, output, ormask, andmask);
3259       generateObjectDistribute(ffan, fm, temp, output);
3260     }
3261   }
3262
3263   protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, TempDescriptor temp,
3264                                    PrintWriter output, int ormask, int andmask) {
3265     if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
3266       output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
3267     } else {
3268       output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
3269     }
3270   }
3271
3272   protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, TempDescriptor temp, PrintWriter output) {
3273     output.println("enqueueObject("+generateTemp(fm, temp)+");");
3274   }
3275
3276   void generateOptionalHeader(PrintWriter headers) {
3277
3278     //GENERATE HEADERS
3279     headers.println("#include \"task.h\"\n\n");
3280     headers.println("#ifndef _OPTIONAL_STRUCT_");
3281     headers.println("#define _OPTIONAL_STRUCT_");
3282
3283     //STRUCT PREDICATEMEMBER
3284     headers.println("struct predicatemember{");
3285     headers.println("int type;");
3286     headers.println("int numdnfterms;");
3287     headers.println("int * flags;");
3288     headers.println("int numtags;");
3289     headers.println("int * tags;\n};\n\n");
3290
3291     //STRUCT OPTIONALTASKDESCRIPTOR
3292     headers.println("struct optionaltaskdescriptor{");
3293     headers.println("struct taskdescriptor * task;");
3294     headers.println("int index;");
3295     headers.println("int numenterflags;");
3296     headers.println("int * enterflags;");
3297     headers.println("int numpredicatemembers;");
3298     headers.println("struct predicatemember ** predicatememberarray;");
3299     headers.println("};\n\n");
3300
3301     //STRUCT TASKFAILURE
3302     headers.println("struct taskfailure {");
3303     headers.println("struct taskdescriptor * task;");
3304     headers.println("int index;");
3305     headers.println("int numoptionaltaskdescriptors;");
3306     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
3307
3308     //STRUCT FSANALYSISWRAPPER
3309     headers.println("struct fsanalysiswrapper{");
3310     headers.println("int  flags;");
3311     headers.println("int numtags;");
3312     headers.println("int * tags;");
3313     headers.println("int numtaskfailures;");
3314     headers.println("struct taskfailure ** taskfailurearray;");
3315     headers.println("int numoptionaltaskdescriptors;");
3316     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
3317
3318     //STRUCT CLASSANALYSISWRAPPER
3319     headers.println("struct classanalysiswrapper{");
3320     headers.println("int type;");
3321     headers.println("int numotd;");
3322     headers.println("struct optionaltaskdescriptor ** otdarray;");
3323     headers.println("int numfsanalysiswrappers;");
3324     headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
3325
3326     headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
3327
3328     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
3329     while(taskit.hasNext()) {
3330       TaskDescriptor td=(TaskDescriptor)taskit.next();
3331       headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
3332     }
3333
3334   }
3335
3336   //CHECK OVER THIS -- THERE COULD BE SOME ERRORS HERE
3337   int generateOptionalPredicate(Predicate predicate, OptionalTaskDescriptor otd, ClassDescriptor cdtemp, PrintWriter output) {
3338     int predicateindex = 0;
3339     //iterate through the classes concerned by the predicate
3340     Set c_vard = predicate.vardescriptors;
3341     Hashtable<TempDescriptor, Integer> slotnumber=new Hashtable<TempDescriptor, Integer>();
3342     int current_slot=0;
3343
3344     for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext(); ) {
3345       VarDescriptor vard = (VarDescriptor)vard_it.next();
3346       TypeDescriptor typed = vard.getType();
3347
3348       //generate for flags
3349       HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
3350       output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3351       int numberterms=0;
3352       if (fen_hashset!=null) {
3353         for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext(); ) {
3354           FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
3355           if (fen!=null) {
3356             DNFFlag dflag=fen.getDNF();
3357             numberterms+=dflag.size();
3358
3359             Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
3360
3361             for(int j=0; j<dflag.size(); j++) {
3362               if (j!=0)
3363                 output.println(",");
3364               Vector term=dflag.get(j);
3365               int andmask=0;
3366               int checkmask=0;
3367               for(int k=0; k<term.size(); k++) {
3368                 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
3369                 FlagDescriptor fd=dfa.getFlag();
3370                 boolean negated=dfa.getNegated();
3371                 int flagid=1<<((Integer)flags.get(fd)).intValue();
3372                 andmask|=flagid;
3373                 if (!negated)
3374                   checkmask|=flagid;
3375               }
3376               output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
3377             }
3378           }
3379         }
3380       }
3381       output.println("};\n");
3382
3383       //generate for tags
3384       TagExpressionList tagel = predicate.tags.get(vard.getSymbol());
3385       output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3386       int numtags = 0;
3387       if (tagel!=null) {
3388         for(int j=0; j<tagel.numTags(); j++) {
3389           if (j!=0)
3390             output.println(",");
3391           TempDescriptor tmp=tagel.getTemp(j);
3392           if (!slotnumber.containsKey(tmp)) {
3393             Integer slotint=new Integer(current_slot++);
3394             slotnumber.put(tmp,slotint);
3395           }
3396           int slot=slotnumber.get(tmp).intValue();
3397           output.println("/* slot */"+ slot+", /*tagid*/"+state.getTagId(tmp.getTag()));
3398         }
3399         numtags = tagel.numTags();
3400       }
3401       output.println("};");
3402
3403       //store the result into a predicatemember struct
3404       output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
3405       output.println("/*type*/"+typed.getClassDesc().getId()+",");
3406       output.println("/* number of dnf terms */"+numberterms+",");
3407       output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3408       output.println("/* number of tag */"+numtags+",");
3409       output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3410       output.println("};\n");
3411       predicateindex++;
3412     }
3413
3414
3415     //generate an array that stores the entire predicate
3416     output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3417     for( int j = 0; j<predicateindex; j++) {
3418       if( j != predicateindex-1) output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3419       else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3420     }
3421     output.println("};\n");
3422     return predicateindex;
3423   }
3424
3425
3426   void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> safeexecution, Hashtable optionaltaskdescriptors) {
3427     generateOptionalHeader(headers);
3428     //GENERATE STRUCTS
3429     output.println("#include \"optionalstruct.h\"\n\n");
3430     output.println("#include \"stdlib.h\"\n");
3431
3432     HashSet processedcd = new HashSet();
3433     int maxotd=0;
3434     Enumeration e = safeexecution.keys();
3435     while (e.hasMoreElements()) {
3436       int numotd=0;
3437       //get the class
3438       ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
3439       Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);       //will be used several times
3440
3441       //Generate the struct of optionals
3442       Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
3443       numotd = c_otd.size();
3444       if(maxotd<numotd) maxotd = numotd;
3445       if( !c_otd.isEmpty() ) {
3446         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext(); ) {
3447           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
3448
3449           //generate the int arrays for the predicate
3450           Predicate predicate = otd.predicate;
3451           int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
3452           TreeSet<Integer> fsset=new TreeSet<Integer>();
3453           //iterate through possible FSes corresponding to
3454           //the state when entering
3455
3456           for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext(); ) {
3457             FlagState fs = (FlagState)fses.next();
3458             int flagid=0;
3459             for(Iterator flags = fs.getFlags(); flags.hasNext(); ) {
3460               FlagDescriptor flagd = (FlagDescriptor)flags.next();
3461               int id=1<<((Integer)flaginfo.get(flagd)).intValue();
3462               flagid|=id;
3463             }
3464             fsset.add(new Integer(flagid));
3465             //tag information not needed because tag
3466             //changes are not tolerated.
3467           }
3468
3469           output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3470           boolean needcomma=false;
3471           for(Iterator<Integer> it=fsset.iterator(); it.hasNext(); ) {
3472             if(needcomma)
3473               output.print(", ");
3474             output.println(it.next());
3475           }
3476
3477           output.println("};\n");
3478
3479
3480           //generate optionaltaskdescriptor that actually
3481           //includes exit fses, predicate and the task
3482           //concerned
3483           output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
3484           output.println("&task_"+otd.td.getSafeSymbol()+",");
3485           output.println("/*index*/"+otd.getIndex()+",");
3486           output.println("/*number of enter flags*/"+fsset.size()+",");
3487           output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3488           output.println("/*number of members */"+predicateindex+",");
3489           output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3490           output.println("};\n");
3491         }
3492       } else
3493         continue;
3494       // if there are no optionals, there is no need to build the rest of the struct
3495
3496       output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
3497       c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
3498       if( !c_otd.isEmpty() ) {
3499         boolean needcomma=false;
3500         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext(); ) {
3501           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
3502           if(needcomma)
3503             output.println(",");
3504           needcomma=true;
3505           output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3506         }
3507       }
3508       output.println("};\n");
3509
3510       //get all the possible flagstates reachable by an object
3511       Hashtable hashtbtemp = safeexecution.get(cdtemp);
3512       int fscounter = 0;
3513       TreeSet fsts=new TreeSet(new FlagComparator(flaginfo));
3514       fsts.addAll(hashtbtemp.keySet());
3515       for(Iterator fsit=fsts.iterator(); fsit.hasNext(); ) {
3516         FlagState fs = (FlagState)fsit.next();
3517         fscounter++;
3518
3519         //get the set of OptionalTaskDescriptors corresponding
3520         HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)hashtbtemp.get(fs);
3521         //iterate through the OptionalTaskDescriptors and
3522         //store the pointers to the optionals struct (see on
3523         //top) into an array
3524
3525         output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
3526         for(Iterator<OptionalTaskDescriptor> mos = ordertd(availabletasks).iterator(); mos.hasNext(); ) {
3527           OptionalTaskDescriptor mm = mos.next();
3528           if(!mos.hasNext())
3529             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
3530           else
3531             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3532         }
3533
3534         output.println("};\n");
3535
3536         //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
3537
3538         int flagid=0;
3539         for(Iterator flags = fs.getFlags(); flags.hasNext(); ) {
3540           FlagDescriptor flagd = (FlagDescriptor)flags.next();
3541           int id=1<<((Integer)flaginfo.get(flagd)).intValue();
3542           flagid|=id;
3543         }
3544
3545         //process tag information
3546
3547         int tagcounter = 0;
3548         boolean first = true;
3549         Enumeration tag_enum = fs.getTags();
3550         output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
3551         while(tag_enum.hasMoreElements()) {
3552           tagcounter++;
3553           TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement();
3554           if(first==true)
3555             first = false;
3556           else
3557             output.println(", ");
3558           output.println("/*tagid*/"+state.getTagId(tagd));
3559         }
3560         output.println("};");
3561
3562         Set<TaskIndex> tiset=sa.getTaskIndex(fs);
3563         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext(); ) {
3564           TaskIndex ti=itti.next();
3565           if (ti.isRuntime())
3566             continue;
3567
3568           Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
3569
3570           output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
3571           boolean needcomma=false;
3572           for(Iterator<OptionalTaskDescriptor> otdit=ordertd(otdset).iterator(); otdit.hasNext(); ) {
3573             OptionalTaskDescriptor otd=otdit.next();
3574             if(needcomma)
3575               output.print(", ");
3576             needcomma=true;
3577             output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3578           }
3579           output.println("};");
3580
3581           output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
3582           output.print("&task_"+ti.getTask().getSafeSymbol()+", ");
3583           output.print(ti.getIndex()+", ");
3584           output.print(otdset.size()+", ");
3585           output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
3586           output.println("};");
3587         }
3588
3589         tiset=sa.getTaskIndex(fs);
3590         boolean needcomma=false;
3591         int runtimeti=0;
3592         output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
3593         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext(); ) {
3594           TaskIndex ti=itti.next();
3595           if (ti.isRuntime()) {
3596             runtimeti++;
3597             continue;
3598           }
3599           if (needcomma)
3600             output.print(", ");
3601           needcomma=true;
3602           output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
3603         }
3604         output.println("};\n");
3605
3606         //Store the result in fsanalysiswrapper
3607
3608         output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
3609         output.println("/*flag*/"+flagid+",");
3610         output.println("/* number of tags*/"+tagcounter+",");
3611         output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3612         output.println("/* numtask failures */"+(tiset.size()-runtimeti)+",");
3613         output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3614         output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
3615         output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
3616         output.println("};\n");
3617
3618       }
3619
3620       //Build the array of fsanalysiswrappers
3621       output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
3622       boolean needcomma=false;
3623       for(int i = 0; i<fscounter; i++) {
3624         if (needcomma) output.print(",");
3625         output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
3626         needcomma=true;
3627       }
3628       output.println("};");
3629
3630       //Build the classanalysiswrapper referring to the previous array
3631       output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
3632       output.println("/*type*/"+cdtemp.getId()+",");
3633       output.println("/*numotd*/"+numotd+",");
3634       output.println("otdarray"+cdtemp.getSafeSymbol()+",");
3635       output.println("/* number of fsanalysiswrappers */"+fscounter+",");
3636       output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
3637       processedcd.add(cdtemp);
3638     }
3639
3640     //build an array containing every classes for which code has been build
3641     output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
3642     for(int i=0; i<state.numClasses(); i++) {
3643       ClassDescriptor cn=cdarray[i];
3644       if (i>0)
3645         output.print(", ");
3646       if ((cn != null) && (processedcd.contains(cn)))
3647         output.print("&classanalysiswrapper_"+cn.getSafeSymbol());
3648       else
3649         output.print("NULL");
3650     }
3651     output.println("};");
3652
3653     output.println("#define MAXOTD "+maxotd);
3654     headers.println("#endif");
3655   }
3656
3657   public List<OptionalTaskDescriptor> ordertd(Set<OptionalTaskDescriptor> otdset) {
3658     Relation r=new Relation();
3659     for(Iterator<OptionalTaskDescriptor>otdit=otdset.iterator(); otdit.hasNext(); ) {
3660       OptionalTaskDescriptor otd=otdit.next();
3661       TaskIndex ti=new TaskIndex(otd.td, otd.getIndex());
3662       r.put(ti, otd);
3663     }
3664
3665     LinkedList<OptionalTaskDescriptor> l=new LinkedList<OptionalTaskDescriptor>();
3666     for(Iterator it=r.keySet().iterator(); it.hasNext(); ) {
3667       Set s=r.get(it.next());
3668       for(Iterator it2=s.iterator(); it2.hasNext(); ) {
3669         OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next();
3670         l.add(otd);
3671       }
3672     }
3673
3674     return l;
3675   }
3676
3677
3678
3679   // either create and register an extension object with buildcode
3680   // or look at the following option of subclassing BuildCode
3681   private Vector<BuildCodeExtension> extensions;
3682
3683   // note that extensions are invoked in the order they are added
3684   // to BuildCode
3685   public void registerExtension( BuildCodeExtension bcx ) {
3686     extensions.add( bcx );
3687   }
3688
3689
3690   // override these methods in a subclass of BuildCode
3691   // to generate code for additional systems
3692   protected void printExtraArrayFields(PrintWriter outclassdefs) {
3693   }
3694   protected void outputTransCode(PrintWriter output) {
3695   }
3696   protected void buildCodeSetup() {
3697   }
3698   protected void generateSizeArrayExtensions(PrintWriter outclassdefs) {
3699   }
3700   protected void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {
3701   }
3702   protected void preCodeGenInitialization() {
3703   }
3704   protected void postCodeGenCleanUp() {
3705   }
3706   protected void additionalCodeGen(PrintWriter outmethodheader,
3707                                    PrintWriter outstructs,
3708                                    PrintWriter outmethod) {
3709   }
3710   protected void additionalCodeAtTopOfMain(PrintWriter outmethod) {
3711   }
3712   protected void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar) {
3713   }
3714   protected void additionalCodeAtBottomOfMain(PrintWriter outmethod) {
3715   }
3716   protected void additionalIncludesMethodsImplementation(PrintWriter outmethod) {
3717   }
3718   protected void additionalIncludesStructsHeader(PrintWriter outstructs) {
3719   }
3720   protected void additionalClassObjectFields(PrintWriter outclassdefs) {
3721   }
3722   protected void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod) {
3723   }
3724   protected void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm) {
3725   }
3726   protected void additionalCodePreNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
3727   }
3728   protected void additionalCodePostNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
3729   }
3730
3731   private void printSourceLineNumber(FlatMethod fm, FlatNode fn, PrintWriter output) {
3732     // we do not print out line number if no one explicitly set the number
3733     if(fn.getNumLine()!=-1) {
3734
3735       int lineNum=fn.getNumLine();
3736
3737       // do not generate the line number if it is same as the previous one
3738       boolean needtoprint;
3739       if(fn.prev.size()==0) {
3740         needtoprint=true;
3741       } else {
3742         needtoprint=false;
3743       }
3744
3745       for(int i=0; i<fn.prev.size(); i++) {
3746         int prevLineNum=((FlatNode)fn.prev.get(i)).getNumLine();
3747         if(prevLineNum!=lineNum) {
3748           needtoprint=true;
3749           break;
3750         }
3751       }
3752       if(needtoprint) {
3753         output.println("// "+fm.getMethod().getClassDesc().getSourceFileName()+":"+fn.getNumLine());
3754       }
3755     }
3756   }
3757
3758 }
3759
3760
3761
3762
3763
3764