throw away commented code
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
1 package IR.Flat;
2 import IR.Tree.Modifiers;
3 import IR.Tree.FlagExpressionNode;
4 import IR.Tree.DNFFlag;
5 import IR.Tree.DNFFlagAtom;
6 import IR.Tree.TagExpressionList;
7 import IR.Tree.OffsetNode;
8 import IR.*;
9
10 import java.util.*;
11 import java.io.*;
12
13 import Util.Relation;
14 import Analysis.TaskStateAnalysis.FlagState;
15 import Analysis.TaskStateAnalysis.FlagComparator;
16 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
17 import Analysis.TaskStateAnalysis.Predicate;
18 import Analysis.TaskStateAnalysis.SafetyAnalysis;
19 import Analysis.TaskStateAnalysis.TaskIndex;
20 import Analysis.Locality.LocalityAnalysis;
21 import Analysis.Locality.LocalityBinding;
22 import Analysis.Locality.DiscoverConflicts;
23 import Analysis.Locality.DCWrapper;
24 import Analysis.Locality.DelayComputation;
25 import Analysis.Locality.BranchAnalysis;
26 import Analysis.CallGraph.CallGraph;
27 import Analysis.Prefetch.*;
28 import Analysis.Loops.WriteBarrier;
29 import Analysis.Loops.GlobalFieldType;
30 import Analysis.Locality.TypeAnalysis;
31 import Util.CodePrinter;
32
33 public class BuildCode {
34   State state;
35   Hashtable temptovar;
36   Hashtable paramstable;
37   Hashtable tempstable;
38   Hashtable fieldorder;
39   Hashtable flagorder;
40   int tag=0;
41   String localsprefix="___locals___";
42   String localsprefixaddr="&"+localsprefix;
43   String localsprefixderef=localsprefix+".";
44   String fcrevert="___fcrevert___";
45   String paramsprefix="___params___";
46   String oidstr="___nextobject___";
47   String nextobjstr="___nextobject___";
48   String localcopystr="___localcopy___";
49   public static boolean GENERATEPRECISEGC=false;
50   public static String PREFIX="";
51   public static String arraytype="ArrayObject";
52   public static int flagcount = 0;
53   Virtual virtualcalls;
54   TypeUtil typeutil;
55   protected int maxtaskparams=0;
56   private int maxcount=0;
57   ClassDescriptor[] cdarray;
58   TypeDescriptor[] arraytable;
59   LocalityAnalysis locality;
60   Hashtable<LocalityBinding, TempDescriptor> reverttable;
61   Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>> backuptable;
62   SafetyAnalysis sa;
63   PrefetchAnalysis pa;
64   WriteBarrier wb;
65   DiscoverConflicts dc;
66   DiscoverConflicts recorddc;
67   DCWrapper delaycomp;
68   CallGraph callgraph;
69   Hashtable<String, ClassDescriptor> printedfieldstbl;
70
71
72   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) {
73     this(st, temptovar, typeutil, null, sa, pa);
74   }
75
76   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa) {
77     this(st, temptovar, typeutil, locality, null, pa);
78   }
79
80   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa ) {
81     this.sa=sa;
82     this.pa=pa;
83     state=st;
84     callgraph=new CallGraph(state);
85     if (state.SINGLETM)
86       oidstr="___objlocation___";
87     this.temptovar=temptovar;
88     paramstable=new Hashtable();
89     tempstable=new Hashtable();
90     fieldorder=new Hashtable();
91     flagorder=new Hashtable();
92     this.typeutil=typeutil;
93     virtualcalls=new Virtual(state,locality);
94     if (locality!=null) {
95       this.locality=locality;
96       this.reverttable=new Hashtable<LocalityBinding, TempDescriptor>();
97       this.backuptable=new Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>>();
98       this.wb=new WriteBarrier(locality, st);
99     }
100     if (state.SINGLETM&&state.DCOPTS) {
101       TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
102       GlobalFieldType gft=new GlobalFieldType(callgraph, st, typeutil.getMain());
103       this.dc=new DiscoverConflicts(locality, st, typeanalysis, gft);
104       dc.doAnalysis();
105     }
106     if (state.DELAYCOMP) {
107       TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
108       GlobalFieldType gft=new GlobalFieldType(callgraph, st, typeutil.getMain());
109       delaycomp=new DCWrapper(locality, st, typeanalysis, gft);
110       dc=delaycomp.getConflicts();
111       recorddc=new DiscoverConflicts(locality, st, typeanalysis, delaycomp.getCannotDelayMap(), true, true, null);
112       recorddc.doAnalysis();
113     }
114     printedfieldstbl = new Hashtable<String, ClassDescriptor>();
115   }
116
117   /** The buildCode method outputs C code for all the methods.  The Flat
118    * versions of the methods must already be generated and stored in
119    * the State object. */
120   PrintWriter outsandbox=null;
121
122   public void buildCode() {
123     /* Create output streams to write to */
124     PrintWriter outclassdefs=null;
125     PrintWriter outstructs=null;
126     PrintWriter outrepairstructs=null;
127     PrintWriter outmethodheader=null;
128     PrintWriter outmethod=null;
129     PrintWriter outvirtual=null;
130     PrintWriter outtask=null;
131     PrintWriter outtaskdefs=null;
132     PrintWriter outoptionalarrays=null;
133     PrintWriter optionalheaders=null;
134     PrintWriter outglobaldefs=null;
135
136     try {
137       if (state.SANDBOX) {
138                                 outsandbox=new CodePrinter(new FileOutputStream(PREFIX+"sandboxdefs.c"), true);
139       }
140       outstructs=new CodePrinter(new FileOutputStream(PREFIX+"structdefs.h"), true);
141       outmethodheader=new CodePrinter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
142       outclassdefs=new CodePrinter(new FileOutputStream(PREFIX+"classdefs.h"), true);
143       if(state.MGC) {
144         // TODO add version for normal Java later
145                                 outglobaldefs=new CodePrinter(new FileOutputStream(PREFIX+"globaldefs.h"), true);
146       }
147       outmethod=new CodePrinter(new FileOutputStream(PREFIX+"methods.c"), true);
148       outvirtual=new CodePrinter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
149       if (state.TASK) {
150                                 outtask=new CodePrinter(new FileOutputStream(PREFIX+"task.h"), true);
151                                 outtaskdefs=new CodePrinter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
152                                 if (state.OPTIONAL) {
153                                         outoptionalarrays=new CodePrinter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
154                                         optionalheaders=new CodePrinter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
155                                 }
156       }
157       if (state.structfile!=null) {
158                                 outrepairstructs=new CodePrinter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
159       }
160     } catch (Exception e) {
161       e.printStackTrace();
162       System.exit(-1);
163     }
164                 
165                 /* Fix field safe symbols due to shadowing */
166                 FieldShadow.handleFieldShadow(state);
167
168     /* Build the virtual dispatch tables */
169     buildVirtualTables(outvirtual);
170
171     /* Tag the methods that are invoked by static blocks */
172     tagMethodInvokedByStaticBlock();
173     
174     /* Output includes */
175     outmethodheader.println("#ifndef METHODHEADERS_H");
176     outmethodheader.println("#define METHODHEADERS_H");
177     outmethodheader.println("#include \"structdefs.h\"");
178     if (state.DSM)
179       outmethodheader.println("#include \"dstm.h\"");
180     if (state.SANDBOX) {
181       outmethodheader.println("#include \"sandbox.h\"");
182     }
183     if (state.EVENTMONITOR) {
184       outmethodheader.println("#include \"monitor.h\"");
185     }
186     if (state.SINGLETM) {
187       outmethodheader.println("#include \"tm.h\"");
188       outmethodheader.println("#include \"delaycomp.h\"");
189       outmethodheader.println("#include \"inlinestm.h\"");
190     }
191     if (state.ABORTREADERS) {
192       outmethodheader.println("#include \"abortreaders.h\"");
193       outmethodheader.println("#include <setjmp.h>");
194     }
195
196
197     additionalIncludesMethodsHeader( outmethodheader );
198
199
200     /* Output Structures */
201     outputStructs(outstructs);
202
203     // Output the C class declarations
204     // These could mutually reference each other
205     
206     if(state.MGC) {
207       // TODO add version for normal Java later
208                         outglobaldefs.println("#ifndef __GLOBALDEF_H_");
209                         outglobaldefs.println("#define __GLOBALDEF_H_");
210                         outglobaldefs.println("");
211                         outglobaldefs.println("struct global_defs_t {");
212     }
213     
214     outclassdefs.println("#ifndef __CLASSDEF_H_");
215     outclassdefs.println("#define __CLASSDEF_H_");
216     outputClassDeclarations(outclassdefs, outglobaldefs);
217
218     // Output function prototypes and structures for parameters
219     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
220     while(it.hasNext()) {
221       ClassDescriptor cn=(ClassDescriptor)it.next();
222       generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs);
223     }
224     outclassdefs.println("#endif");
225     outclassdefs.close();
226     if(state.MGC) {
227       // TODO add version for normal Java later
228                         outglobaldefs.println("};");
229                         outglobaldefs.println("");
230                         outglobaldefs.println("extern struct global_defs_t * global_defs_p;");
231                         outglobaldefs.println("#endif");
232                         outglobaldefs.flush();
233                         outglobaldefs.close();
234     }
235
236     if (state.TASK) {
237       /* Map flags to integers */
238       /* The runtime keeps track of flags using these integers */
239       it=state.getClassSymbolTable().getDescriptorsIterator();
240       while(it.hasNext()) {
241         ClassDescriptor cn=(ClassDescriptor)it.next();
242         mapFlags(cn);
243       }
244       /* Generate Tasks */
245       generateTaskStructs(outstructs, outmethodheader);
246
247       /* Outputs generic task structures if this is a task
248          program */
249       outputTaskTypes(outtask);
250     }
251
252
253     // an opportunity for subclasses to do extra
254     // initialization
255     preCodeGenInitialization();
256
257
258     /* Build the actual methods */
259     outputMethods(outmethod);
260
261     
262     // opportunity for subclasses to gen extra code
263     additionalCodeGen( outmethodheader,
264                        outstructs,
265                        outmethod );
266
267
268     if (state.TASK) {
269       /* Output code for tasks */
270       outputTaskCode(outtaskdefs, outmethod);
271       outtaskdefs.close();
272       /* Record maximum number of task parameters */
273       outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
274     } else if (state.main!=null) {
275       /* Generate main method */
276       outputMainMethod(outmethod);
277     }
278
279     /* Generate information for task with optional parameters */
280     if (state.TASK&&state.OPTIONAL) {
281       generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
282       outoptionalarrays.close();
283     }
284     
285     /* Output structure definitions for repair tool */
286     if (state.structfile!=null) {
287       buildRepairStructs(outrepairstructs);
288       outrepairstructs.close();
289     }
290     
291     /* Close files */
292     outmethodheader.println("#endif");
293     outmethodheader.close();
294     outmethod.close();
295     outstructs.println("#endif");
296     outstructs.close();
297
298
299
300     postCodeGenCleanUp();
301   }
302
303
304   
305   /* This method goes though the call graph and tag those methods that are 
306    * invoked inside static blocks
307    */
308   protected void tagMethodInvokedByStaticBlock() {
309     if(state.MGC) {
310       Iterator it_sclasses = this.state.getSClassSymbolTable().getDescriptorsIterator();
311       MethodDescriptor current_md=null;
312       HashSet tovisit=new HashSet();
313       HashSet visited=new HashSet();
314
315       while(it_sclasses.hasNext()) {
316         ClassDescriptor cd = (ClassDescriptor)it_sclasses.next();
317         MethodDescriptor md = (MethodDescriptor)cd.getMethodTable().get("staticblocks");
318         if(md != null) {
319           tovisit.add(md);
320         }
321       }
322
323       while(!tovisit.isEmpty()) {
324         current_md=(MethodDescriptor)tovisit.iterator().next();
325         tovisit.remove(current_md);
326         visited.add(current_md);
327         Iterator it_callee = this.callgraph.getCalleeSet(current_md).iterator();
328         while(it_callee.hasNext()) {
329           Descriptor d = (Descriptor)it_callee.next();
330           if(d instanceof MethodDescriptor) {
331             if(!visited.contains(d)) {
332               ((MethodDescriptor)d).setIsInvokedByStatic(true);
333               tovisit.add(d);
334             }
335           }
336         }
337       }
338     } // TODO for normal Java version
339   }
340   
341   /* This code generates code for each static block and static field 
342    * initialization.*/
343   protected void outputStaticBlocks(PrintWriter outmethod) {
344     //  execute all the static blocks and all the static field initializations
345     // TODO
346   }
347   
348   /* This code generates code to create a Class object for each class for 
349    * getClass() method.
350    * */
351   protected void outputClassObjects(PrintWriter outmethod) {
352     // for each class, initialize its Class object
353     // TODO
354   }
355
356   /* This code just generates the main C method for java programs.
357    * The main C method packs up the arguments into a string array
358    * and passes it to the java main method. */
359
360   protected void outputMainMethod(PrintWriter outmethod) {
361     outmethod.println("int main(int argc, const char *argv[]) {");
362     outmethod.println("  int i;");
363     
364     outputStaticBlocks(outmethod);
365     outputClassObjects(outmethod);
366
367
368     additionalCodeAtTopOfMain( outmethod );
369
370
371     if (state.DSM) {
372       if (state.DSMRECOVERYSTATS) {
373         outmethod.println("#ifdef RECOVERYSTATS \n");
374         outmethod.println("handle();\n");
375         outmethod.println("#endif\n");
376       } else {
377         outmethod.println("#if defined(TRANSSTATS) || defined(RECOVERYSTATS) \n");
378         outmethod.println("handle();\n");
379         outmethod.println("#endif\n");
380       }
381     }
382     
383     if (state.THREAD||state.DSM||state.SINGLETM) {
384       outmethod.println("initializethreads();");
385     }
386     if (state.DSM) {
387       outmethod.println("if (dstmStartup(argv[1])) {");
388       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
389         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-2);");
390       } else {
391         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-2);");
392       }
393     } else {
394       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
395         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
396       } else {
397         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
398       }
399     }
400     if (state.DSM) {
401       outmethod.println("  for(i=2;i<argc;i++) {");
402     } else
403       outmethod.println("  for(i=1;i<argc;i++) {");
404     outmethod.println("    int length=strlen(argv[i]);");
405     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
406       outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
407     } else {
408       outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
409     }
410     if (state.DSM)
411       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-2]=newstring;");
412     else
413       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
414     outmethod.println("  }");
415
416     MethodDescriptor md=typeutil.getMain();
417     ClassDescriptor cd=typeutil.getMainClass();
418
419     outmethod.println("   {");
420     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
421       if (state.DSM||state.SINGLETM) {
422         outmethod.print("       struct "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
423       } else
424         outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
425     outmethod.println("1, NULL,"+"stringarray};");
426       if (state.DSM||state.SINGLETM)
427         outmethod.println("     "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
428       else
429         outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
430     } else {
431       if (state.DSM||state.SINGLETM)
432         outmethod.println("     "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
433       else
434         outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
435     }
436     outmethod.println("   }");
437
438     if (state.DSM) {
439       outmethod.println("}");
440     }
441
442     if (state.THREAD||state.DSM||state.SINGLETM) {
443       outmethod.println("pthread_mutex_lock(&gclistlock);");
444       outmethod.println("threadcount--;");
445       outmethod.println("pthread_cond_signal(&gccond);");
446       outmethod.println("pthread_mutex_unlock(&gclistlock);");
447     }
448
449     if (state.DSM||state.SINGLETM) {
450       outmethod.println("#if defined(TRANSSTATS) \n");
451       outmethod.println("printf(\"******  Transaction Stats   ******\\n\");");
452       outmethod.println("printf(\"numTransCommit= %d\\n\", numTransCommit);");
453       outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);");
454       outmethod.println("printf(\"nSoftAbort= %d\\n\", nSoftAbort);");
455       if (state.DSM) {
456         outmethod.println("printf(\"nchashSearch= %d\\n\", nchashSearch);");
457         outmethod.println("printf(\"nmhashSearch= %d\\n\", nmhashSearch);");
458         outmethod.println("printf(\"nprehashSearch= %d\\n\", nprehashSearch);");
459         outmethod.println("printf(\"ndirtyCacheObj= %d\\n\", ndirtyCacheObj);");
460         outmethod.println("printf(\"nRemoteReadSend= %d\\n\", nRemoteSend);");
461         outmethod.println("printf(\"bytesSent= %d\\n\", bytesSent);");
462         outmethod.println("printf(\"bytesRecv= %d\\n\", bytesRecv);");
463         outmethod.println("printf(\"totalObjSize= %d\\n\", totalObjSize);");
464         outmethod.println("printf(\"sendRemoteReq= %d\\n\", sendRemoteReq);");
465         outmethod.println("printf(\"getResponse= %d\\n\", getResponse);");
466       } else if (state.SINGLETM) {
467         outmethod.println("printf(\"nSoftAbortAbort= %d\\n\", nSoftAbortAbort);");
468         outmethod.println("printf(\"nSoftAbortCommit= %d\\n\", nSoftAbortCommit);");
469         outmethod.println("#ifdef STMSTATS\n");
470         outmethod.println("for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {\n");
471         outmethod.println("  printf(\"typesCausingAbort[%2d] numaccess= %5d numabort= %3d\\n\", i, typesCausingAbort[i].numaccess, typesCausingAbort[i].numabort);\n");
472         outmethod.println("}\n");
473         outmethod.println("#endif\n");
474         outmethod.println("fflush(stdout);");
475       }
476       outmethod.println("#endif\n");
477     }
478
479     if (state.EVENTMONITOR) {
480       outmethod.println("dumpdata();");
481     }
482
483     if (state.THREAD||state.SINGLETM)
484       outmethod.println("pthread_exit(NULL);");
485
486
487     additionalCodeAtBottomOfMain( outmethod );
488
489
490     outmethod.println("}");
491   }
492
493   /* This method outputs code for each task. */
494
495   private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
496     /* Compile task based program */
497     outtaskdefs.println("#include \"task.h\"");
498     outtaskdefs.println("#include \"methodheaders.h\"");
499     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
500     while(taskit.hasNext()) {
501       TaskDescriptor td=(TaskDescriptor)taskit.next();
502       FlatMethod fm=state.getMethodFlat(td);
503       generateFlatMethod(fm, null, outmethod);
504       generateTaskDescriptor(outtaskdefs, fm, td);
505     }
506
507     //Output task descriptors
508     taskit=state.getTaskSymbolTable().getDescriptorsIterator();
509     outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
510     boolean first=true;
511     while(taskit.hasNext()) {
512       TaskDescriptor td=(TaskDescriptor)taskit.next();
513       if (first)
514         first=false;
515       else
516         outtaskdefs.println(",");
517       outtaskdefs.print("&task_"+td.getSafeSymbol());
518     }
519     outtaskdefs.println("};");
520
521     outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
522   }
523
524
525   /* This method outputs most of the methods.c file.  This includes
526    * some standard includes and then an array with the sizes of
527    * objets and array that stores supertype and then the code for
528    * the Java methods.. */
529   protected void outputMethods(PrintWriter outmethod) {
530     outmethod.println("#include \"methodheaders.h\"");
531     outmethod.println("#include \"virtualtable.h\"");
532     outmethod.println("#include \"runtime.h\"");
533
534     // always include: compiler directives will leave out
535     // instrumentation when option is not set
536     outmethod.println("#include \"coreprof/coreprof.h\"");
537
538     if (state.SANDBOX) {
539       outmethod.println("#include \"sandboxdefs.c\"");
540     }
541     if (state.DSM) {
542       outmethod.println("#include \"addPrefetchEnhance.h\"");
543       outmethod.println("#include \"localobjects.h\"");
544     }
545     if (state.FASTCHECK) {
546       outmethod.println("#include \"localobjects.h\"");
547     }
548     if(state.MULTICORE) {
549       if(state.TASK) {
550         outmethod.println("#include \"task.h\"");
551       }
552           outmethod.println("#include \"multicoreruntime.h\"");
553           outmethod.println("#include \"runtime_arch.h\"");
554     }
555     if (state.THREAD||state.DSM||state.SINGLETM) {
556       outmethod.println("#include <thread.h>");
557     }
558     if(state.MGC) {
559       outmethod.println("#include \"thread.h\"");
560     } 
561     if (state.main!=null) {
562       outmethod.println("#include <string.h>");
563     }
564     if (state.CONSCHECK) {
565       outmethod.println("#include \"checkers.h\"");
566     }
567
568
569     additionalIncludesMethodsImplementation( outmethod );
570
571
572     if(state.MGC) {
573       // TODO add version for normal Java later
574     outmethod.println("struct global_defs_t * global_defs_p;");
575     }
576     //Store the sizes of classes & array elements
577     generateSizeArray(outmethod);
578
579     //Store table of supertypes
580     generateSuperTypeTable(outmethod);
581     
582     //Store the layout of classes
583     generateLayoutStructs(outmethod);
584
585
586     additionalCodeAtTopMethodsImplementation( outmethod );
587
588
589     /* Generate code for methods */
590     if (state.DSM||state.SINGLETM) {
591       for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator(); lbit.hasNext();) {
592         LocalityBinding lb=lbit.next();
593         MethodDescriptor md=lb.getMethod();
594         FlatMethod fm=state.getMethodFlat(md);
595         wb.analyze(lb);
596         if (!md.getModifiers().isNative()) {
597           generateFlatMethod(fm, lb, outmethod);
598         }
599       }
600     } else {
601       Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
602       while(classit.hasNext()) {
603         ClassDescriptor cn=(ClassDescriptor)classit.next();
604         Iterator methodit=cn.getMethods();
605         while(methodit.hasNext()) {
606           /* Classify parameters */
607           MethodDescriptor md=(MethodDescriptor)methodit.next();
608           FlatMethod fm=state.getMethodFlat(md);
609           if (!md.getModifiers().isNative()) {
610             generateFlatMethod(fm, null, outmethod);
611           }
612         }
613       }
614     }
615   }
616
617   protected void outputStructs(PrintWriter outstructs) {
618     outstructs.println("#ifndef STRUCTDEFS_H");
619     outstructs.println("#define STRUCTDEFS_H");
620     outstructs.println("#include \"classdefs.h\"");
621     outstructs.println("#ifndef INTPTR");
622     outstructs.println("#ifdef BIT64");
623     outstructs.println("#define INTPTR long");
624     outstructs.println("#else");
625     outstructs.println("#define INTPTR int");
626     outstructs.println("#endif");
627     outstructs.println("#endif");
628
629
630     additionalIncludesStructsHeader( outstructs );
631
632
633     /* Output #defines that the runtime uses to determine type
634      * numbers for various objects it needs */
635     outstructs.println("#define MAXCOUNT "+maxcount);
636     if (state.DSM||state.SINGLETM) {
637       LocalityBinding lbrun=new LocalityBinding(typeutil.getRun(), false);
638       if (state.DSM) {
639         lbrun.setGlobalThis(LocalityAnalysis.GLOBAL);
640       }
641       else if (state.SINGLETM) {
642         lbrun.setGlobalThis(LocalityAnalysis.NORMAL);
643       }
644       outstructs.println("#define RUNMETHOD "+virtualcalls.getLocalityNumber(lbrun));
645     }
646
647     if (state.DSMTASK) {
648       LocalityBinding lbexecute = new LocalityBinding(typeutil.getExecute(), false);
649       if(state.DSM)
650         lbexecute.setGlobalThis(LocalityAnalysis.GLOBAL);
651       else if( state.SINGLETM)
652         lbexecute.setGlobalThis(LocalityAnalysis.NORMAL);
653       outstructs.println("#define EXECUTEMETHOD " + virtualcalls.getLocalityNumber(lbexecute));
654     }
655
656     outstructs.println("#define STRINGARRAYTYPE "+
657                        (state.getArrayNumber(
658                           (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
659
660     outstructs.println("#define OBJECTARRAYTYPE "+
661                        (state.getArrayNumber(
662                           (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
663
664
665     outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
666     outstructs.println("#define CHARARRAYTYPE "+
667                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
668
669     outstructs.println("#define BYTEARRAYTYPE "+
670                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
671
672     outstructs.println("#define BYTEARRAYARRAYTYPE "+
673                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
674
675     outstructs.println("#define NUMCLASSES "+state.numClasses());
676     int totalClassSize = state.numClasses() + state.numArrays();
677     outstructs.println("#define TOTALNUMCLASSANDARRAY "+ totalClassSize);
678     if (state.TASK) {
679       outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
680       outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
681       outstructs.println("#define TAGARRAYTYPE "+
682                          (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
683     }
684   }
685
686   protected void outputClassDeclarations(PrintWriter outclassdefs, PrintWriter outglobaldefs) {
687     if (state.THREAD||state.DSM||state.SINGLETM)
688       outclassdefs.println("#include <pthread.h>");
689     outclassdefs.println("#ifndef INTPTR");
690     outclassdefs.println("#ifdef BIT64");
691     outclassdefs.println("#define INTPTR long");
692     outclassdefs.println("#else");
693     outclassdefs.println("#define INTPTR int");
694     outclassdefs.println("#endif");
695     outclassdefs.println("#endif");
696     if(state.OPTIONAL)
697       outclassdefs.println("#include \"optionalstruct.h\"");
698     outclassdefs.println("struct "+arraytype+";");
699     /* Start by declaring all structs */
700     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
701     while(it.hasNext()) {
702       ClassDescriptor cn=(ClassDescriptor)it.next();
703       outclassdefs.println("struct "+cn.getSafeSymbol()+";");
704       
705       if(state.MGC) {
706         // TODO add version for normal Java later
707       if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
708         // this class has static fields/blocks, need to add a global flag to 
709         // indicate if its static fields have been initialized and/or if its
710         // static blocks have been executed
711         outglobaldefs.println("  int "+cn.getSafeSymbol()+"static_block_exe_flag;");
712       }
713       
714       // for each class, create a global object
715       outglobaldefs.println("  struct ___Object___ "+cn.getSafeSymbol()+"classobj;");
716       }
717     }
718     outclassdefs.println("");
719     //Print out definition for array type
720     outclassdefs.println("struct "+arraytype+" {");
721     outclassdefs.println("  int type;");
722
723     
724     additionalClassObjectFields( outclassdefs );
725
726
727     if (state.EVENTMONITOR) {
728       outclassdefs.println("  int objuid;");
729     }
730     if (state.THREAD) {
731       outclassdefs.println("  pthread_t tid;");
732       outclassdefs.println("  void * lockentry;");
733       outclassdefs.println("  int lockcount;");
734     }
735     if(state.MGC) {
736       outclassdefs.println("  int mutex;");  
737       outclassdefs.println("  int objlock;");
738       if(state.MULTICOREGC) {
739         outclassdefs.println("  int marked;");
740       }
741     } 
742     if (state.TASK) {
743       outclassdefs.println("  int flag;");
744       if(!state.MULTICORE) {
745         outclassdefs.println("  void * flagptr;");
746       } else {
747         outclassdefs.println("  int version;");
748         outclassdefs.println("  int * lock;");  // lock entry for this obj
749         outclassdefs.println("  int mutex;");  
750         outclassdefs.println("  int lockcount;");
751         if(state.MULTICOREGC) {
752           outclassdefs.println("  int marked;");
753         }
754       }
755       if(state.OPTIONAL) {
756         outclassdefs.println("  int numfses;");
757         outclassdefs.println("  int * fses;");
758       }
759     }
760
761     printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs);
762     printedfieldstbl.clear();
763
764     if (state.STMARRAY) {
765       outclassdefs.println("  int lowindex;");
766       outclassdefs.println("  int highindex;");
767     }
768     if (state.ARRAYPAD)
769       outclassdefs.println("  int paddingforarray;");
770     if (state.DUALVIEW) {
771       outclassdefs.println("  int arrayversion;");
772     }
773
774     outclassdefs.println("  int ___length___;");
775     outclassdefs.println("};\n");
776     
777     if(state.MGC) {
778       // TODO add version for normal Java later
779     outclassdefs.println("");
780     //Print out definition for Class type 
781     outclassdefs.println("struct Class {");
782     outclassdefs.println("  int type;");
783
784
785     additionalClassObjectFields( outclassdefs );
786
787
788     if (state.EVENTMONITOR) {
789       outclassdefs.println("  int objuid;");
790     }
791     if (state.THREAD) {
792       outclassdefs.println("  pthread_t tid;");
793       outclassdefs.println("  void * lockentry;");
794       outclassdefs.println("  int lockcount;");
795     }
796     if(state.MGC) {
797       outclassdefs.println("  int mutex;");  
798       outclassdefs.println("  int objlock;");
799       if(state.MULTICOREGC) {
800         outclassdefs.println("  int marked;");
801       }
802     } 
803     if (state.TASK) {
804       outclassdefs.println("  int flag;");
805       if(!state.MULTICORE) {
806         outclassdefs.println("  void * flagptr;");
807       } else {
808         outclassdefs.println("  int version;");
809         outclassdefs.println("  int * lock;");  // lock entry for this obj
810         outclassdefs.println("  int mutex;");  
811         outclassdefs.println("  int lockcount;");
812         if(state.MULTICOREGC) {
813           outclassdefs.println("  int marked;");
814         }
815       }
816       if(state.OPTIONAL) {
817         outclassdefs.println("  int numfses;");
818         outclassdefs.println("  int * fses;");
819       }
820     }
821     printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs);
822     printedfieldstbl.clear();
823     outclassdefs.println("};\n");
824     }
825     
826     outclassdefs.println("");
827     outclassdefs.println("extern int classsize[];");
828     outclassdefs.println("extern int hasflags[];");
829     outclassdefs.println("extern unsigned INTPTR * pointerarray[];");
830     outclassdefs.println("extern int supertypes[];");
831     outclassdefs.println("");
832   }
833
834   /** Prints out definitions for generic task structures */
835
836   private void outputTaskTypes(PrintWriter outtask) {
837     outtask.println("#ifndef _TASK_H");
838     outtask.println("#define _TASK_H");
839     outtask.println("struct parameterdescriptor {");
840     outtask.println("int type;");
841     outtask.println("int numberterms;");
842     outtask.println("int *intarray;");
843     outtask.println("void * queue;");
844     outtask.println("int numbertags;");
845     outtask.println("int *tagarray;");
846     outtask.println("};");
847
848     outtask.println("struct taskdescriptor {");
849     outtask.println("void * taskptr;");
850     outtask.println("int numParameters;");
851     outtask.println("  int numTotal;");
852     outtask.println("struct parameterdescriptor **descriptorarray;");
853     outtask.println("char * name;");
854     outtask.println("};");
855     outtask.println("extern struct taskdescriptor * taskarray[];");
856     outtask.println("extern numtasks;");
857     outtask.println("#endif");
858   }
859
860
861   private void buildRepairStructs(PrintWriter outrepairstructs) {
862     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
863     while(classit.hasNext()) {
864       ClassDescriptor cn=(ClassDescriptor)classit.next();
865       outrepairstructs.println("structure "+cn.getSymbol()+" {");
866       outrepairstructs.println("  int __type__;");
867       if (state.TASK) {
868         outrepairstructs.println("  int __flag__;");
869         if(!state.MULTICORE) {
870           outrepairstructs.println("  int __flagptr__;");
871         }
872       }
873       printRepairStruct(cn, outrepairstructs);
874       outrepairstructs.println("}\n");
875     }
876
877     for(int i=0; i<state.numArrays(); i++) {
878       TypeDescriptor tdarray=arraytable[i];
879       TypeDescriptor tdelement=tdarray.dereference();
880       outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
881       outrepairstructs.println("  int __type__;");
882       printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
883       outrepairstructs.println("  int length;");
884       outrepairstructs.println("}\n");
885     }
886   }
887
888   private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
889     ClassDescriptor sp=cn.getSuperDesc();
890     if (sp!=null)
891       printRepairStruct(sp, output);
892
893     Vector fields=(Vector)fieldorder.get(cn);
894
895     for(int i=0; i<fields.size(); i++) {
896       FieldDescriptor fd=(FieldDescriptor)fields.get(i);
897       if (fd.getType().isArray()) {
898         output.println("  "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
899       } else if (fd.getType().isClass())
900         output.println("  "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
901       else if (fd.getType().isFloat())
902         output.println("  int "+fd.getSymbol()+"; /* really float */");
903       else
904         output.println("  "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
905     }
906   }
907
908   /** This method outputs TaskDescriptor information */
909   private void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
910     for (int i=0; i<task.numParameters(); i++) {
911       VarDescriptor param_var=task.getParameter(i);
912       TypeDescriptor param_type=task.getParamType(i);
913       FlagExpressionNode param_flag=task.getFlag(param_var);
914       TagExpressionList param_tag=task.getTag(param_var);
915
916       int dnfterms;
917       if (param_flag==null) {
918         output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
919         output.println("0x0, 0x0 };");
920         dnfterms=1;
921       } else {
922         DNFFlag dflag=param_flag.getDNF();
923         dnfterms=dflag.size();
924
925         Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
926         output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
927         for(int j=0; j<dflag.size(); j++) {
928           if (j!=0)
929             output.println(",");
930           Vector term=dflag.get(j);
931           int andmask=0;
932           int checkmask=0;
933           for(int k=0; k<term.size(); k++) {
934             DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
935             FlagDescriptor fd=dfa.getFlag();
936             boolean negated=dfa.getNegated();
937             int flagid=1<<((Integer)flags.get(fd)).intValue();
938             andmask|=flagid;
939             if (!negated)
940               checkmask|=flagid;
941           }
942           output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
943         }
944         output.println("};");
945       }
946
947       output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
948       if (param_tag!=null)
949         for(int j=0; j<param_tag.numTags(); j++) {
950           if (j!=0)
951             output.println(",");
952           /* for each tag we need */
953           /* which slot it is */
954           /* what type it is */
955           TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
956           TempDescriptor tmp=param_tag.getTemp(j);
957           int slot=fm.getTagInt(tmp);
958           output.println(slot+", "+state.getTagId(tvd.getTag()));
959         }
960       output.println("};");
961
962       output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
963       output.println("/* type */"+param_type.getClassDesc().getId()+",");
964       output.println("/* number of DNF terms */"+dnfterms+",");
965       output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
966       output.println("0,");
967       if (param_tag!=null)
968         output.println("/* number of tags */"+param_tag.numTags()+",");
969       else
970         output.println("/* number of tags */ 0,");
971       output.println("parametertag_"+i+"_"+task.getSafeSymbol());
972       output.println("};");
973     }
974
975
976     output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
977     for (int i=0; i<task.numParameters(); i++) {
978       if (i!=0)
979         output.println(",");
980       output.print("&parameter_"+i+"_"+task.getSafeSymbol());
981     }
982     output.println("};");
983
984     output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
985     output.println("&"+task.getSafeSymbol()+",");
986     output.println("/* number of parameters */" +task.numParameters() + ",");
987     int numtotal=task.numParameters()+fm.numTags();
988     output.println("/* number total parameters */" +numtotal + ",");
989     output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
990     output.println("\""+task.getSymbol()+"\"");
991     output.println("};");
992   }
993
994
995   /** The buildVirtualTables method outputs the virtual dispatch
996    * tables for methods. */
997
998   protected void buildVirtualTables(PrintWriter outvirtual) {
999     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
1000     while(classit.hasNext()) {
1001       ClassDescriptor cd=(ClassDescriptor)classit.next();
1002       if (virtualcalls.getMethodCount(cd)>maxcount)
1003         maxcount=virtualcalls.getMethodCount(cd);
1004     }
1005     MethodDescriptor[][] virtualtable=null;
1006     LocalityBinding[][] lbvirtualtable=null;
1007     if (state.DSM||state.SINGLETM)
1008       lbvirtualtable=new LocalityBinding[state.numClasses()+state.numArrays()][maxcount];
1009     else
1010       virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
1011
1012     /* Fill in virtual table */
1013     classit=state.getClassSymbolTable().getDescriptorsIterator();
1014     while(classit.hasNext()) {
1015       ClassDescriptor cd=(ClassDescriptor)classit.next();
1016       if(cd.isInterface()) {
1017         continue;
1018       }
1019       if (state.DSM||state.SINGLETM)
1020         fillinRow(cd, lbvirtualtable, cd.getId());
1021       else
1022         fillinRow(cd, virtualtable, cd.getId());
1023     }
1024
1025     ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
1026     Iterator arrayit=state.getArrayIterator();
1027     while(arrayit.hasNext()) {
1028       TypeDescriptor td=(TypeDescriptor)arrayit.next();
1029       int id=state.getArrayNumber(td);
1030       if (state.DSM||state.SINGLETM)
1031         fillinRow(objectcd, lbvirtualtable, id+state.numClasses());
1032       else
1033         fillinRow(objectcd, virtualtable, id+state.numClasses());
1034     }
1035
1036     outvirtual.print("void * virtualtable[]={");
1037     boolean needcomma=false;
1038     for(int i=0; i<state.numClasses()+state.numArrays(); i++) {
1039       for(int j=0; j<maxcount; j++) {
1040         if (needcomma)
1041           outvirtual.print(", ");
1042         if ((state.DSM||state.SINGLETM)&&lbvirtualtable[i][j]!=null) {
1043           LocalityBinding lb=lbvirtualtable[i][j];
1044           MethodDescriptor md=lb.getMethod();
1045           outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1046         } else if (!(state.DSM||state.SINGLETM)&&virtualtable[i][j]!=null) {
1047           MethodDescriptor md=virtualtable[i][j];
1048           outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1049         } else {
1050           outvirtual.print("0");
1051         }
1052         needcomma=true;
1053       }
1054       outvirtual.println("");
1055     }
1056     outvirtual.println("};");
1057     outvirtual.close();
1058   }
1059
1060   private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
1061     /* Get inherited methods */
1062     if (cd.getSuperDesc()!=null)
1063       fillinRow(cd.getSuperDesc(), virtualtable, rownum);
1064     if(state.MGC) {
1065       // TODO add version for normal Java later
1066       Iterator it_sifs = cd.getSuperInterfaces();
1067       while(it_sifs.hasNext()) {
1068         ClassDescriptor superif = (ClassDescriptor)it_sifs.next();
1069         fillinRow(superif, virtualtable, rownum);
1070       }
1071     }
1072     /* Override them with our methods */
1073     for(Iterator it=cd.getMethods(); it.hasNext();) {
1074       MethodDescriptor md=(MethodDescriptor)it.next();
1075       if (md.isStatic()||md.getReturnType()==null)
1076         continue;
1077       int methodnum=virtualcalls.getMethodNumber(md);
1078       virtualtable[rownum][methodnum]=md;
1079     }
1080   }
1081
1082   private void fillinRow(ClassDescriptor cd, LocalityBinding[][] virtualtable, int rownum) {
1083     /* Get inherited methods */
1084     if (cd.getSuperDesc()!=null)
1085       fillinRow(cd.getSuperDesc(), virtualtable, rownum);
1086     /* Override them with our methods */
1087     if (locality.getClassBindings(cd)!=null)
1088       for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cd).iterator(); lbit.hasNext();) {
1089         LocalityBinding lb=lbit.next();
1090         MethodDescriptor md=lb.getMethod();
1091         //Is the method static or a constructor
1092         if (md.isStatic()||md.getReturnType()==null)
1093           continue;
1094         int methodnum=virtualcalls.getLocalityNumber(lb);
1095         virtualtable[rownum][methodnum]=lb;
1096       }
1097   }
1098
1099   /** Generate array that contains the sizes of class objects.  The
1100    * object allocation functions in the runtime use this
1101    * information. */
1102
1103   private void generateSizeArray(PrintWriter outclassdefs) {
1104     outclassdefs.print("extern struct prefetchCountStats * evalPrefetch;\n");
1105     outclassdefs.print("#ifdef TRANSSTATS \n");
1106     outclassdefs.print("extern int numTransAbort;\n");
1107     outclassdefs.print("extern int numTransCommit;\n");
1108     outclassdefs.print("extern int nSoftAbort;\n");
1109     if (state.DSM) {
1110       outclassdefs.print("extern int nchashSearch;\n");
1111       outclassdefs.print("extern int nmhashSearch;\n");
1112       outclassdefs.print("extern int nprehashSearch;\n");
1113       outclassdefs.print("extern int ndirtyCacheObj;\n");
1114       outclassdefs.print("extern int nRemoteSend;\n");
1115       outclassdefs.print("extern int sendRemoteReq;\n");
1116       outclassdefs.print("extern int getResponse;\n");
1117       outclassdefs.print("extern int bytesSent;\n");
1118       outclassdefs.print("extern int bytesRecv;\n");
1119       outclassdefs.print("extern int totalObjSize;\n");
1120       outclassdefs.print("extern void handle();\n");
1121     } else if (state.SINGLETM) {
1122       outclassdefs.println("extern int nSoftAbortAbort;");
1123       outclassdefs.println("extern int nSoftAbortCommit;");
1124       outclassdefs.println("#ifdef STMSTATS\n");
1125       outclassdefs.println("extern objtypestat_t typesCausingAbort[];");
1126       outclassdefs.println("#endif\n");
1127     }
1128     outclassdefs.print("#endif\n");
1129
1130     outclassdefs.print("int numprefetchsites = " + pa.prefetchsiteid + ";\n");
1131
1132
1133     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
1134     cdarray=new ClassDescriptor[state.numClasses()];
1135     cdarray[0] = null;
1136     while(it.hasNext()) {
1137       ClassDescriptor cd=(ClassDescriptor)it.next();
1138       if(!cd.isInterface()) {
1139         cdarray[cd.getId()]=cd;
1140       }
1141     }
1142
1143     arraytable=new TypeDescriptor[state.numArrays()];
1144
1145     Iterator arrayit=state.getArrayIterator();
1146     while(arrayit.hasNext()) {
1147       TypeDescriptor td=(TypeDescriptor)arrayit.next();
1148       int id=state.getArrayNumber(td);
1149       arraytable[id]=td;
1150     }
1151
1152
1153
1154     /* Print out types */
1155     outclassdefs.println("/* ");
1156     for(int i=0; i<state.numClasses(); i++) {
1157       ClassDescriptor cd=cdarray[i];
1158       if(cd == null) {
1159         outclassdefs.println("NULL " + i);
1160       } else {
1161         outclassdefs.println(cd +"  "+i);
1162       }
1163     }
1164
1165     for(int i=0; i<state.numArrays(); i++) {
1166       TypeDescriptor arraytd=arraytable[i];
1167       outclassdefs.println(arraytd.toPrettyString() +"  "+(i+state.numClasses()));
1168     }
1169
1170     outclassdefs.println("*/");
1171
1172
1173     outclassdefs.print("int classsize[]={");
1174
1175     boolean needcomma=false;
1176     for(int i=0; i<state.numClasses(); i++) {
1177       if (needcomma)
1178         outclassdefs.print(", ");
1179       if(i>0) {
1180         outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
1181       } else {
1182         outclassdefs.print("0");
1183       }
1184       needcomma=true;
1185     }
1186
1187
1188     for(int i=0; i<state.numArrays(); i++) {
1189       if (needcomma)
1190         outclassdefs.print(", ");
1191       TypeDescriptor tdelement=arraytable[i].dereference();
1192       if (tdelement.isArray()||tdelement.isClass()||tdelement.isNull())
1193         outclassdefs.print("sizeof(void *)");
1194       else
1195         outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
1196       needcomma=true;
1197     }
1198
1199     outclassdefs.println("};");
1200
1201     ClassDescriptor objectclass=typeutil.getClass(TypeUtil.ObjectClass);
1202     needcomma=false;
1203     outclassdefs.print("int typearray[]={");
1204     for(int i=0; i<state.numClasses(); i++) {
1205       ClassDescriptor cd=cdarray[i];
1206       ClassDescriptor supercd=i>0?cd.getSuperDesc():null;
1207       if (needcomma)
1208         outclassdefs.print(", ");
1209       if (supercd==null)
1210         outclassdefs.print("-1");
1211       else
1212         outclassdefs.print(supercd.getId());
1213       needcomma=true;
1214     }
1215
1216     for(int i=0; i<state.numArrays(); i++) {
1217       TypeDescriptor arraytd=arraytable[i];
1218       ClassDescriptor arraycd=arraytd.getClassDesc();
1219       if (arraycd==null) {
1220         if (needcomma)
1221           outclassdefs.print(", ");
1222         outclassdefs.print(objectclass.getId());
1223         needcomma=true;
1224         continue;
1225       }
1226       ClassDescriptor cd=arraycd.getSuperDesc();
1227       int type=-1;
1228       while(cd!=null) {
1229         TypeDescriptor supertd=new TypeDescriptor(cd);
1230         supertd.setArrayCount(arraytd.getArrayCount());
1231         type=state.getArrayNumber(supertd);
1232         if (type!=-1) {
1233           type+=state.numClasses();
1234           break;
1235         }
1236         cd=cd.getSuperDesc();
1237       }
1238       if (needcomma)
1239         outclassdefs.print(", ");
1240       outclassdefs.print(type);
1241       needcomma=true;
1242     }
1243
1244     outclassdefs.println("};");
1245
1246     needcomma=false;
1247
1248
1249     outclassdefs.print("int typearray2[]={");
1250     for(int i=0; i<state.numArrays(); i++) {
1251       TypeDescriptor arraytd=arraytable[i];
1252       ClassDescriptor arraycd=arraytd.getClassDesc();
1253       if (arraycd==null) {
1254         if (needcomma)
1255           outclassdefs.print(", ");
1256         outclassdefs.print("-1");
1257         needcomma=true;
1258         continue;
1259       }
1260       ClassDescriptor cd=arraycd.getSuperDesc();
1261       int level=arraytd.getArrayCount()-1;
1262       int type=-1;
1263       for(; level>0; level--) {
1264         TypeDescriptor supertd=new TypeDescriptor(objectclass);
1265         supertd.setArrayCount(level);
1266         type=state.getArrayNumber(supertd);
1267         if (type!=-1) {
1268           type+=state.numClasses();
1269           break;
1270         }
1271       }
1272       if (needcomma)
1273         outclassdefs.print(", ");
1274       outclassdefs.print(type);
1275       needcomma=true;
1276     }
1277
1278     outclassdefs.println("};");
1279   }
1280
1281   /** Constructs params and temp objects for each method or task.
1282    * These objects tell the compiler which temps need to be
1283    * allocated.  */
1284
1285   protected void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
1286     MethodDescriptor md=fm.getMethod();
1287     TaskDescriptor task=fm.getTask();
1288     Set<TempDescriptor> saveset=lb!=null ? locality.getTempSet(lb) : null;
1289     ParamsObject objectparams=md!=null ? new ParamsObject(md,tag++) : new ParamsObject(task, tag++);
1290     if (lb!=null) {
1291       paramstable.put(lb, objectparams);
1292       backuptable.put(lb, new Hashtable<TempDescriptor, TempDescriptor>());
1293     } else if (md!=null)
1294       paramstable.put(md, objectparams);
1295     else
1296       paramstable.put(task, objectparams);
1297
1298     for(int i=0; i<fm.numParameters(); i++) {
1299       TempDescriptor temp=fm.getParameter(i);
1300       TypeDescriptor type=temp.getType();
1301       if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
1302         objectparams.addPtr(temp);
1303       else
1304         objectparams.addPrim(temp);
1305       if(lb!=null&&saveset.contains(temp)) {
1306         backuptable.get(lb).put(temp, temp.createNew());
1307       }
1308     }
1309
1310     for(int i=0; i<fm.numTags(); i++) {
1311       TempDescriptor temp=fm.getTag(i);
1312       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
1313         objectparams.addPtr(temp);
1314       else
1315         objectparams.addPrim(temp);
1316     }
1317
1318     TempObject objecttemps=md!=null ? new TempObject(objectparams,md,tag++) : new TempObject(objectparams, task, tag++);
1319     if (lb!=null)
1320       tempstable.put(lb, objecttemps);
1321     else if (md!=null)
1322       tempstable.put(md, objecttemps);
1323     else
1324       tempstable.put(task, objecttemps);
1325
1326     for(Iterator nodeit=fm.getNodeSet().iterator(); nodeit.hasNext();) {
1327       FlatNode fn=(FlatNode)nodeit.next();
1328       TempDescriptor[] writes=fn.writesTemps();
1329       for(int i=0; i<writes.length; i++) {
1330         TempDescriptor temp=writes[i];
1331         TypeDescriptor type=temp.getType();
1332         if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
1333           objecttemps.addPtr(temp);
1334         else
1335           objecttemps.addPrim(temp);
1336         if(lb!=null&&saveset.contains(temp)&&
1337            !backuptable.get(lb).containsKey(temp))
1338           backuptable.get(lb).put(temp, temp.createNew());
1339       }
1340     }
1341
1342     /* Create backup temps */
1343     if (lb!=null) {
1344       for(Iterator<TempDescriptor> tmpit=backuptable.get(lb).values().iterator(); tmpit.hasNext();) {
1345         TempDescriptor tmp=tmpit.next();
1346         TypeDescriptor type=tmp.getType();
1347         if (type.isPtr()&&((GENERATEPRECISEGC) || (this.state.MULTICOREGC)))
1348           objecttemps.addPtr(tmp);
1349         else
1350           objecttemps.addPrim(tmp);
1351       }
1352       /* Create temp to hold revert table */
1353       if (state.DSM&&(lb.getHasAtomic()||lb.isAtomic())) {
1354         TempDescriptor reverttmp=new TempDescriptor("revertlist", typeutil.getClass(TypeUtil.ObjectClass));
1355         if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
1356           objecttemps.addPtr(reverttmp);
1357         else
1358           objecttemps.addPrim(reverttmp);
1359         reverttable.put(lb, reverttmp);
1360       }
1361     }
1362   }
1363
1364   /** This method outputs the following information about classes
1365    * and arrays:
1366    * (1) For classes, what are the locations of pointers.
1367    * (2) For arrays, does the array contain pointers or primitives.
1368    * (3) For classes, does the class contain flags.
1369    */
1370
1371   private void generateLayoutStructs(PrintWriter output) {
1372     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
1373     while(it.hasNext()) {
1374       ClassDescriptor cn=(ClassDescriptor)it.next();
1375       output.println("unsigned INTPTR "+cn.getSafeSymbol()+"_pointers[]={");
1376       Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
1377       int count=0;
1378       while(allit.hasNext()) {
1379         FieldDescriptor fd=(FieldDescriptor)allit.next();
1380         TypeDescriptor type=fd.getType();
1381         if (state.DSM&&fd.isGlobal())         //Don't GC the global objects for now
1382           continue;
1383         if (type.isPtr())
1384           count++;
1385       }
1386       output.print(count);
1387       allit=cn.getFieldTable().getAllDescriptorsIterator();
1388       while(allit.hasNext()) {
1389         FieldDescriptor fd=(FieldDescriptor)allit.next();
1390         TypeDescriptor type=fd.getType();
1391         if (state.DSM&&fd.isGlobal())         //Don't GC the global objects for now
1392           continue;
1393         if (type.isPtr()) {
1394           output.println(",");
1395           output.print("((unsigned INTPTR)&(((struct "+cn.getSafeSymbol() +" *)0)->"+
1396                                                                  fd.getSafeSymbol()+"))");
1397         }
1398       }
1399       output.println("};");
1400     }
1401     output.println("unsigned INTPTR * pointerarray[]={");
1402     boolean needcomma=false;
1403     for(int i=0; i<state.numClasses(); i++) {
1404       ClassDescriptor cn=cdarray[i];
1405       if (needcomma)
1406         output.println(",");
1407       needcomma=true;
1408       if(cn != null) {
1409         output.print(cn.getSafeSymbol()+"_pointers");
1410       } else {
1411         output.print("NULL");
1412       }
1413     }
1414
1415     for(int i=0; i<state.numArrays(); i++) {
1416       if (needcomma)
1417         output.println(", ");
1418       TypeDescriptor tdelement=arraytable[i].dereference();
1419       if (tdelement.isArray()||tdelement.isClass())
1420         output.print("((unsigned INTPTR *)1)");
1421       else
1422         output.print("0");
1423       needcomma=true;
1424     }
1425
1426     output.println("};");
1427     needcomma=false;
1428     output.println("int hasflags[]={");
1429     for(int i=0; i<state.numClasses(); i++) {
1430       ClassDescriptor cn=cdarray[i];
1431       if (needcomma)
1432         output.println(", ");
1433       needcomma=true;
1434       if ((cn != null) && (cn.hasFlags()))
1435         output.print("1");
1436       else
1437         output.print("0");
1438     }
1439     output.println("};");
1440   }
1441
1442   /** Print out table to give us supertypes */
1443   private void generateSuperTypeTable(PrintWriter output) {
1444     output.println("int supertypes[]={");
1445     boolean needcomma=false;
1446     for(int i=0; i<state.numClasses(); i++) {
1447       ClassDescriptor cn=cdarray[i];
1448       if (needcomma)
1449         output.println(",");
1450       needcomma=true;
1451       if ((cn != null) && (cn.getSuperDesc()!=null)) {
1452         ClassDescriptor cdsuper=cn.getSuperDesc();
1453         output.print(cdsuper.getId());
1454       } else
1455         output.print("-1");
1456     }
1457     output.println("};");
1458   }
1459   
1460   /** Print out table to give us classnames */
1461   /*private void generateClassNameTable(PrintWriter output) {
1462     output.println("char * classname[]={");
1463     boolean needcomma=false;
1464     for(int i=0; i<state.numClasses(); i++) {
1465       ClassDescriptor cn=cdarray[i];
1466       if (needcomma)
1467     output.println(",");
1468       needcomma=true;
1469       if ((cn != null) && (cn.getSuperDesc()!=null)) {
1470     output.print("\"" + cn.getSymbol() + "\"");
1471       } else
1472     output.print("\"\"");
1473     }
1474     output.println("};");
1475   }*/
1476
1477   /** Force consistent field ordering between inherited classes. */
1478
1479   private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout, PrintWriter globaldefout) {
1480     
1481     ClassDescriptor sp=cn.getSuperDesc();
1482     if (sp!=null)
1483       printClassStruct(sp, classdefout, /*globaldefout*/null);
1484     
1485     SymbolTable sitbl = cn.getSuperInterfaceTable();
1486     Iterator it_sifs = sitbl.getDescriptorsIterator();
1487     if(state.MGC) {
1488       while(it_sifs.hasNext()) {
1489         ClassDescriptor si = (ClassDescriptor)it_sifs.next();
1490         printClassStruct(si, classdefout, /*globaldefout*/null);
1491       }
1492     }
1493
1494     if (!fieldorder.containsKey(cn)) {
1495       Vector fields=new Vector();
1496       fieldorder.put(cn,fields);
1497       
1498       Vector fieldvec=cn.getFieldVec();
1499       for(int i=0;i<fieldvec.size();i++) {
1500         FieldDescriptor fd=(FieldDescriptor)fieldvec.get(i);
1501     if(state.MGC) {
1502       if((sp != null) && sp.getFieldTable().contains(fd.getSymbol())) {
1503         // a shadow field
1504       } else {
1505         it_sifs = sitbl.getDescriptorsIterator();
1506         boolean hasprinted = false;
1507         while(it_sifs.hasNext()) {
1508           ClassDescriptor si = (ClassDescriptor)it_sifs.next();
1509           if(si.getFieldTable().contains(fd.getSymbol())) {
1510             hasprinted = true;
1511             break;
1512           }
1513         }
1514         if(hasprinted) {
1515           // this field has been defined in the super class
1516         } else {
1517           fields.add(fd);
1518         }
1519       }
1520     } else {
1521       if ((sp==null) || (!sp.getFieldTable().contains(fd.getSymbol())))
1522         fields.add(fd);
1523     }
1524       }
1525     }
1526     Vector fields=(Vector)fieldorder.get(cn);
1527     
1528     /*Vector */fields = cn.getFieldVec();
1529
1530     for(int i=0; i<fields.size(); i++) {
1531       FieldDescriptor fd=(FieldDescriptor)fields.get(i);
1532       String fstring = fd.getSymbol();
1533       if(printedfieldstbl.containsKey(fstring)) {
1534         printedfieldstbl.put(fstring, cn);
1535         continue;
1536       } else {
1537         printedfieldstbl.put(fstring, cn);
1538       }
1539       if (state.MGC && fd.getType().isClass()
1540           && fd.getType().getClassDesc().isEnum()) {
1541         classdefout.println("  int " + fd.getSafeSymbol() + ";");
1542       } else if (fd.getType().isClass()||fd.getType().isArray()) {
1543         if ((state.MGC) && (fd.isStatic())) {
1544           // TODO add version for normal Java later
1545           // static field
1546           if(globaldefout != null) {
1547             if(fd.isVolatile()) {
1548               globaldefout.println("  volatile struct "+fd.getType().getSafeSymbol()+ " * "+fd.getSafeSymbol()+";");
1549             } else {
1550               globaldefout.println("  struct "+fd.getType().getSafeSymbol()+ " * "+fd.getSafeSymbol()+";");
1551             }
1552           }
1553           classdefout.println("  struct "+fd.getType().getSafeSymbol()+" ** "+fd.getSafeSymbol()+";");
1554         } else if ((state.MGC) && (fd.isVolatile())) {
1555           // TODO add version for normal Java later
1556           // static field
1557           if(globaldefout != null) {
1558             globaldefout.println("  volatile struct "+fd.getType().getSafeSymbol()+ " * "+fd.getSafeSymbol()+";");
1559           }
1560           classdefout.println("  struct"+fd.getType().getSafeSymbol()+" ** "+fd.getSafeSymbol()+";");
1561         } else {
1562         classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
1563         }
1564       } else if ((state.MGC) && (fd.isStatic())) {
1565         // TODO add version for normal Java later
1566         // static field
1567         if(globaldefout != null) {
1568           if(fd.isVolatile()) {
1569             globaldefout.println("  volatile "+fd.getType().getSafeSymbol()+ " "+fd.getSafeSymbol()+";");
1570           } else {
1571             globaldefout.println("  "+fd.getType().getSafeSymbol()+ " "+fd.getSafeSymbol()+";");
1572           }
1573         }
1574         classdefout.println("  "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
1575       } else if ((state.MGC) && (fd.isVolatile())) {
1576         // TODO add version for normal Java later
1577         // static field
1578         if(globaldefout != null) {
1579           globaldefout.println("  volatile "+fd.getType().getSafeSymbol()+ " "+fd.getSafeSymbol()+";");
1580         }
1581         classdefout.println("  "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
1582       } else
1583         classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
1584     }
1585   }
1586
1587
1588   /* Map flags to integers consistently between inherited
1589    * classes. */
1590
1591   protected void mapFlags(ClassDescriptor cn) {
1592     ClassDescriptor sp=cn.getSuperDesc();
1593     if (sp!=null)
1594       mapFlags(sp);
1595     int max=0;
1596     if (!flagorder.containsKey(cn)) {
1597       Hashtable flags=new Hashtable();
1598       flagorder.put(cn,flags);
1599       if (sp!=null) {
1600         Hashtable superflags=(Hashtable)flagorder.get(sp);
1601         Iterator superflagit=superflags.keySet().iterator();
1602         while(superflagit.hasNext()) {
1603           FlagDescriptor fd=(FlagDescriptor)superflagit.next();
1604           Integer number=(Integer)superflags.get(fd);
1605           flags.put(fd, number);
1606           if ((number.intValue()+1)>max)
1607             max=number.intValue()+1;
1608         }
1609       }
1610
1611       Iterator flagit=cn.getFlags();
1612       while(flagit.hasNext()) {
1613         FlagDescriptor fd=(FlagDescriptor)flagit.next();
1614         if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
1615           flags.put(fd, new Integer(max++));
1616       }
1617     }
1618   }
1619
1620
1621   /** This function outputs (1) structures that parameters are
1622    * passed in (when PRECISE GC is enabled) and (2) function
1623    * prototypes for the methods */
1624
1625   protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout, PrintWriter globaldefout) {
1626     /* Output class structure */
1627     classdefout.println("struct "+cn.getSafeSymbol()+" {");
1628     classdefout.println("  int type;");
1629
1630
1631     additionalClassObjectFields( classdefout );
1632
1633
1634     if (state.EVENTMONITOR) {
1635       classdefout.println("  int objuid;");
1636     }
1637     if (state.THREAD) {
1638       classdefout.println("  pthread_t tid;");
1639       classdefout.println("  void * lockentry;");
1640       classdefout.println("  int lockcount;");
1641     }
1642     if(state.MGC) {
1643       classdefout.println("  int mutex;");  
1644       classdefout.println("  int objlock;");
1645       if(state.MULTICOREGC) {
1646         classdefout.println("  int marked;");
1647       }
1648     } 
1649     if (state.TASK) {
1650       classdefout.println("  int flag;");
1651       if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
1652         classdefout.println("  void * flagptr;");
1653       } else if (state.MULTICORE) {
1654         classdefout.println("  int version;");
1655     classdefout.println("  int * lock;");  // lock entry for this obj
1656     classdefout.println("  int mutex;");  
1657     classdefout.println("  int lockcount;");
1658     if(state.MULTICOREGC) {
1659       classdefout.println("  int marked;");
1660     }
1661       }
1662       if (state.OPTIONAL) {
1663         classdefout.println("  int numfses;");
1664         classdefout.println("  int * fses;");
1665       }
1666     }
1667     printClassStruct(cn, classdefout, globaldefout);
1668     printedfieldstbl.clear();
1669     classdefout.println("};\n");
1670
1671     if (state.DSM||state.SINGLETM) {
1672       /* Cycle through LocalityBindings */
1673       HashSet<MethodDescriptor> nativemethods=new HashSet<MethodDescriptor>();
1674       Set<LocalityBinding> lbset=locality.getClassBindings(cn);
1675       if (lbset!=null) {
1676         for(Iterator<LocalityBinding> lbit=lbset.iterator(); lbit.hasNext();) {
1677           LocalityBinding lb=lbit.next();
1678           MethodDescriptor md=lb.getMethod();
1679           if (md.getModifiers().isNative()) {
1680             //make sure we only print a native method once
1681             if (nativemethods.contains(md)) {
1682               FlatMethod fm=state.getMethodFlat(md);
1683               generateTempStructs(fm, lb);
1684               continue;
1685             } else
1686               nativemethods.add(md);
1687           }
1688           generateMethod(cn, md, lb, headersout, output);
1689         }
1690       }
1691       for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1692         MethodDescriptor md=(MethodDescriptor)methodit.next();
1693         if (md.getModifiers().isNative()&&!nativemethods.contains(md)) {
1694           //Need to build param structure for library code
1695           FlatMethod fm=state.getMethodFlat(md);
1696           generateTempStructs(fm, null);
1697           generateMethodParam(cn, md, null, output);
1698         }
1699       }
1700
1701     } else
1702       for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1703         MethodDescriptor md=(MethodDescriptor)methodit.next();
1704         generateMethod(cn, md, null, headersout, output);
1705       }
1706   }
1707
1708   private void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter output) {
1709     /* Output parameter structure */
1710     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1711       ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1712       if ((state.DSM||state.SINGLETM)&&lb!=null)
1713         output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1714       else
1715         output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1716       output.println("  int size;");
1717       output.println("  void * next;");      
1718       for(int i=0; i<objectparams.numPointers(); i++) {
1719         TempDescriptor temp=objectparams.getPointer(i);
1720     if(state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
1721       output.println("  int " + temp.getSafeSymbol() + ";");
1722     } else {
1723       output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1724     }
1725       }
1726       output.println("};\n");
1727     }
1728   }
1729
1730   private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
1731     FlatMethod fm=state.getMethodFlat(md);
1732     generateTempStructs(fm, lb);
1733
1734     ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1735     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md);
1736
1737     generateMethodParam(cn, md, lb, output);
1738
1739     /* Output temp structure */
1740     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1741       if (state.DSM||state.SINGLETM)
1742         output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1743       else
1744         output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1745       output.println("  int size;");
1746       output.println("  void * next;");
1747       for(int i=0; i<objecttemps.numPointers(); i++) {
1748         TempDescriptor temp=objecttemps.getPointer(i);
1749         if (temp.getType().isNull())
1750           output.println("  void * "+temp.getSafeSymbol()+";");
1751         else
1752           output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1753       }
1754       output.println("};\n");
1755     }
1756
1757     /********* Output method declaration ***********/
1758     if (state.DSM||state.SINGLETM) {
1759       headersout.println("#define D"+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1760     } else {
1761       headersout.println("#define D"+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1762     }
1763     /* First the return type */
1764     if (md.getReturnType()!=null) {
1765       if(state.MGC && md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) {
1766         headersout.println("  int ");
1767       } else if (md.getReturnType().isClass()||md.getReturnType().isArray())
1768         headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1769       else
1770         headersout.print(md.getReturnType().getSafeSymbol()+" ");
1771     } else
1772       //catch the constructor case
1773       headersout.print("void ");
1774
1775     /* Next the method name */
1776     if (state.DSM||state.SINGLETM) {
1777       headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1778     } else {
1779       headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1780     }
1781     boolean printcomma=false;
1782     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1783       if (state.DSM||state.SINGLETM) {
1784         headersout.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1785       } else
1786         headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1787       printcomma=true;
1788     }
1789
1790     /*  Output parameter list*/
1791     for(int i=0; i<objectparams.numPrimitives(); i++) {
1792       TempDescriptor temp=objectparams.getPrimitive(i);
1793       if (printcomma)
1794         headersout.print(", ");
1795       printcomma=true;
1796       if(state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
1797         headersout.print("int " + temp.getSafeSymbol());
1798       } else if (temp.getType().isClass()||temp.getType().isArray())
1799         headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1800       else
1801         headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1802     }
1803     headersout.println(");\n");
1804   }
1805
1806
1807   /** This function outputs (1) structures that parameters are
1808    * passed in (when PRECISE GC is enabled) and (2) function
1809    * prototypes for the tasks */
1810
1811   private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
1812     /* Cycle through tasks */
1813     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1814
1815     while(taskit.hasNext()) {
1816       /* Classify parameters */
1817       TaskDescriptor task=(TaskDescriptor)taskit.next();
1818       FlatMethod fm=state.getMethodFlat(task);
1819       generateTempStructs(fm, null);
1820
1821       ParamsObject objectparams=(ParamsObject) paramstable.get(task);
1822       TempObject objecttemps=(TempObject) tempstable.get(task);
1823
1824       /* Output parameter structure */
1825       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1826         output.println("struct "+task.getSafeSymbol()+"_params {");
1827         output.println("  int size;");
1828         output.println("  void * next;");
1829         for(int i=0; i<objectparams.numPointers(); i++) {
1830           TempDescriptor temp=objectparams.getPointer(i);
1831           output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1832         }
1833
1834         output.println("};\n");
1835         if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1836           maxtaskparams=objectparams.numPointers()+fm.numTags();
1837         }
1838       }
1839
1840       /* Output temp structure */
1841       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1842         output.println("struct "+task.getSafeSymbol()+"_locals {");
1843         output.println("  int size;");
1844         output.println("  void * next;");
1845         for(int i=0; i<objecttemps.numPointers(); i++) {
1846           TempDescriptor temp=objecttemps.getPointer(i);
1847           if (temp.getType().isNull())
1848             output.println("  void * "+temp.getSafeSymbol()+";");
1849           else if(temp.getType().isTag())
1850             output.println("  struct "+
1851                            (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1852           else
1853             output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1854         }
1855         output.println("};\n");
1856       }
1857
1858       /* Output task declaration */
1859       headersout.print("void " + task.getSafeSymbol()+"(");
1860
1861       boolean printcomma=false;
1862       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1863         headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1864       } else
1865         headersout.print("void * parameterarray[]");
1866       headersout.println(");\n");
1867     }
1868   }
1869
1870   /***** Generate code for FlatMethod fm. *****/
1871
1872   Hashtable<FlatAtomicEnterNode, AtomicRecord> atomicmethodmap;
1873   static int atomicmethodcount=0;
1874
1875
1876   BranchAnalysis branchanalysis;
1877   private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1878     if (State.PRINTFLAT)
1879       System.out.println(fm.printMethod());
1880     MethodDescriptor md=fm.getMethod();
1881     TaskDescriptor task=fm.getTask();
1882     ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
1883     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : md!=null ? md : task);
1884
1885     HashSet<AtomicRecord> arset=null;
1886     branchanalysis=null;
1887
1888     if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
1889       //create map
1890       if (atomicmethodmap==null)
1891         atomicmethodmap=new Hashtable<FlatAtomicEnterNode, AtomicRecord>();
1892
1893       //fix these so we get right strings for local variables
1894       localsprefixaddr=localsprefix;
1895       localsprefixderef=localsprefix+"->";
1896       arset=new HashSet<AtomicRecord>();
1897
1898       //build branchanalysis
1899       branchanalysis=new BranchAnalysis(locality, lb, delaycomp.getNotReady(lb), delaycomp.livecode(lb), state);
1900       
1901       //Generate commit methods here
1902       for(Iterator<FlatNode> fnit=fm.getNodeSet().iterator();fnit.hasNext();) {
1903         FlatNode fn=fnit.next();
1904         if (fn.kind()==FKind.FlatAtomicEnterNode&&
1905             locality.getAtomic(lb).get(fn.getPrev(0)).intValue()==0&&
1906             delaycomp.needsFission(lb, (FlatAtomicEnterNode) fn)) {
1907           //We have an atomic enter
1908           FlatAtomicEnterNode faen=(FlatAtomicEnterNode) fn;
1909           Set<FlatNode> exitset=faen.getExits();
1910           //generate header
1911           String methodname=md.getSymbol()+(atomicmethodcount++);
1912           AtomicRecord ar=new AtomicRecord();
1913           ar.name=methodname;
1914           arset.add(ar);
1915
1916           atomicmethodmap.put(faen, ar);
1917
1918           //build data structure declaration
1919           output.println("struct atomicprimitives_"+methodname+" {");
1920
1921           Set<FlatNode> recordset=delaycomp.livecode(lb);
1922           Set<TempDescriptor> liveinto=delaycomp.liveinto(lb, faen, recordset);
1923           Set<TempDescriptor> liveout=delaycomp.liveout(lb, faen);
1924           Set<TempDescriptor> liveoutvirtualread=delaycomp.liveoutvirtualread(lb, faen);
1925           ar.livein=liveinto;
1926           ar.reallivein=new HashSet(liveinto);
1927           ar.liveout=liveout;
1928           ar.liveoutvirtualread=liveoutvirtualread;
1929
1930
1931           for(Iterator<TempDescriptor> it=liveinto.iterator(); it.hasNext();) {
1932             TempDescriptor tmp=it.next();
1933             //remove the pointers
1934             if (tmp.getType().isPtr()) {
1935               it.remove();
1936             } else {
1937               //let's print it here
1938               output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
1939             }
1940           }
1941           for(Iterator<TempDescriptor> it=liveout.iterator(); it.hasNext();) {
1942             TempDescriptor tmp=it.next();
1943             //remove the pointers
1944             if (tmp.getType().isPtr()) {
1945               it.remove();
1946             } else if (!liveinto.contains(tmp)) {
1947               //let's print it here
1948               output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
1949             }
1950           }
1951           output.println("};");
1952
1953           //print out method name
1954           output.println("void "+methodname+"(struct "+ cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix+", struct "+ cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals *"+localsprefix+", struct atomicprimitives_"+methodname+" * primitives) {");
1955           //build code for commit method
1956           
1957           //first define local primitives
1958           Set<TempDescriptor> alltemps=delaycomp.alltemps(lb, faen, recordset);
1959           for(Iterator<TempDescriptor> tmpit=alltemps.iterator();tmpit.hasNext();) {
1960             TempDescriptor tmp=tmpit.next();
1961             if (!tmp.getType().isPtr()) {
1962               if (liveinto.contains(tmp)||liveoutvirtualread.contains(tmp)) {
1963                 //read from live into set
1964                 output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+"=primitives->"+tmp.getSafeSymbol()+";");
1965               } else {
1966                 //just define
1967                 output.println(tmp.getType().getSafeSymbol()+" "+tmp.getSafeSymbol()+";");
1968               }
1969             }
1970           }
1971           //turn off write barrier generation
1972           wb.turnoff();
1973           state.SINGLETM=false;
1974           generateCode(faen, fm, lb, exitset, output, false);
1975           state.SINGLETM=true;
1976           //turn on write barrier generation
1977           wb.turnon();
1978           output.println("}\n\n");
1979         }
1980       }
1981     }
1982     //redefine these back to normal
1983
1984     localsprefixaddr="&"+localsprefix;
1985     localsprefixderef=localsprefix+".";
1986
1987     generateHeader(fm, lb, md!=null ? md : task,output);
1988     TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1989
1990     if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
1991       for(Iterator<AtomicRecord> arit=arset.iterator();arit.hasNext();) {
1992         AtomicRecord ar=arit.next();
1993         output.println("struct atomicprimitives_"+ar.name+" primitives_"+ar.name+";");
1994       }
1995     }
1996
1997     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1998       if (md!=null&&(state.DSM||state.SINGLETM))
1999         output.print("   struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
2000       else if (md!=null&&!(state.DSM||state.SINGLETM))
2001         output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
2002       else
2003         output.print("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
2004       output.print(objecttemp.numPointers()+",");
2005       output.print(paramsprefix);
2006       for(int j=0; j<objecttemp.numPointers(); j++)
2007         output.print(", NULL");
2008       output.println("};");
2009     }
2010
2011     for(int i=0; i<objecttemp.numPrimitives(); i++) {
2012       TempDescriptor td=objecttemp.getPrimitive(i);
2013       TypeDescriptor type=td.getType();
2014       if (type.isNull() && !type.isArray())
2015         output.println("   void * "+td.getSafeSymbol()+";");
2016       else if (state.MGC && type.isClass() && type.getClassDesc().isEnum()) {
2017         output.println("   int " + td.getSafeSymbol() + ";");
2018       } else if (type.isClass()||type.isArray())
2019         output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
2020       else
2021         output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
2022     }
2023
2024
2025
2026     additionalCodeAtTopFlatMethodBody( output, fm );
2027     
2028
2029
2030     /* Check to see if we need to do a GC if this is a
2031      * multi-threaded program...*/
2032
2033     if (((state.OOOJAVA||state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) 
2034         || this.state.MULTICOREGC) {
2035       //Don't bother if we aren't in recursive methods...The loops case will catch it
2036       if (callgraph.getAllMethods(md).contains(md)) {
2037         if (state.DSM&&lb.isAtomic())
2038           output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");");
2039         else if (this.state.MULTICOREGC) {
2040           output.println("if(gcflag) gc("+localsprefixaddr+");");
2041         } else {
2042           output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
2043         }
2044       }
2045     }
2046     
2047     if(state.MGC) {
2048       // TODO add version for normal Java later
2049     if(fm.getMethod().isStaticBlock()) {
2050       // a static block, check if it has been executed
2051       output.println("  if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag != 0) {");
2052       output.println("    return;");
2053       output.println("  }");
2054       output.println("");
2055     }
2056     if((!fm.getMethod().isStaticBlock()) && (fm.getMethod().getReturnType() == null) && (cn != null)){
2057       // is a constructor, check and output initialization of the static fields
2058       // here does not initialize the static fields of the class, instead it 
2059       // redirect the corresponding fields in the object to the global_defs_p
2060       Vector fields=cn.getFieldVec();
2061
2062       for(int i=0; i<fields.size(); i++) {
2063         FieldDescriptor fd=(FieldDescriptor)fields.get(i);
2064         if(fd.isStatic()) {
2065           // static field
2066           output.println(generateTemp(fm,fm.getParameter(0),lb)+"->"+fd.getSafeSymbol()+"=&(global_defs_p->"+fd.getSafeSymbol()+");");
2067         }
2068       }
2069     }
2070     }
2071
2072     generateCode(fm.getNext(0), fm, lb, null, output, true);
2073
2074     output.println("}\n\n");
2075   }
2076
2077
2078
2079   protected void generateCode(FlatNode first,
2080                               FlatMethod fm,
2081                               LocalityBinding lb,
2082                               Set<FlatNode> stopset,
2083                               PrintWriter output, 
2084                               boolean firstpass) {
2085
2086     /* Assign labels to FlatNode's if necessary.*/
2087
2088     Hashtable<FlatNode, Integer> nodetolabel;
2089
2090     if (state.DELAYCOMP&&!firstpass)
2091       nodetolabel=dcassignLabels(first, stopset);      
2092     else
2093       nodetolabel=assignLabels(first, stopset);      
2094     
2095     Set<FlatNode> storeset=null;
2096     HashSet<FlatNode> genset=null;
2097     HashSet<FlatNode> refset=null;
2098     Set<FlatNode> unionset=null;
2099
2100     if (state.DELAYCOMP&&!lb.isAtomic()&&lb.getHasAtomic()) {
2101       storeset=delaycomp.livecode(lb);
2102       genset=new HashSet<FlatNode>();
2103       if (state.STMARRAY&&!state.DUALVIEW) {
2104         refset=new HashSet<FlatNode>();
2105         refset.addAll(delaycomp.getDeref(lb));
2106         refset.removeAll(delaycomp.getCannotDelay(lb));
2107         refset.removeAll(delaycomp.getOther(lb));
2108       }
2109       if (firstpass) {
2110         genset.addAll(delaycomp.getCannotDelay(lb));
2111         genset.addAll(delaycomp.getOther(lb));
2112       } else {
2113         genset.addAll(delaycomp.getNotReady(lb));
2114         if (state.STMARRAY&&!state.DUALVIEW) {
2115           genset.removeAll(refset);
2116         }
2117       }
2118       unionset=new HashSet<FlatNode>();
2119       unionset.addAll(storeset);
2120       unionset.addAll(genset);
2121       if (state.STMARRAY&&!state.DUALVIEW)
2122         unionset.addAll(refset);
2123     }
2124     
2125     /* Do the actual code generation */
2126     FlatNode current_node=null;
2127     HashSet tovisit=new HashSet();
2128     HashSet visited=new HashSet();
2129     if (!firstpass)
2130       tovisit.add(first.getNext(0));
2131     else
2132       tovisit.add(first);
2133     while(current_node!=null||!tovisit.isEmpty()) {
2134       if (current_node==null) {
2135         current_node=(FlatNode)tovisit.iterator().next();
2136         tovisit.remove(current_node);
2137       } else if (tovisit.contains(current_node)) {
2138         tovisit.remove(current_node);
2139       }
2140       visited.add(current_node);
2141       if (nodetolabel.containsKey(current_node)) {
2142         output.println("L"+nodetolabel.get(current_node)+":");
2143       }
2144       if (state.INSTRUCTIONFAILURE) {
2145         if (state.THREAD||state.DSM||state.SINGLETM) {
2146           output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
2147         } else
2148           output.println("if ((--instructioncount)==0) injectinstructionfailure();");
2149       }
2150       if (current_node.numNext()==0||stopset!=null&&stopset.contains(current_node)) {
2151         output.print("   ");
2152         if (!state.DELAYCOMP||firstpass) {
2153           generateFlatNode(fm, lb, current_node, output);
2154         } else {
2155           //store primitive variables in out set
2156           AtomicRecord ar=atomicmethodmap.get((FlatAtomicEnterNode)first);
2157           Set<TempDescriptor> liveout=ar.liveout;
2158           for(Iterator<TempDescriptor> tmpit=liveout.iterator();tmpit.hasNext();) {
2159             TempDescriptor tmp=tmpit.next();
2160             output.println("primitives->"+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
2161           }
2162         }
2163         if (state.OOOJAVA && stopset!=null) {
2164           assert first.getPrev( 0 ) instanceof FlatSESEEnterNode;
2165           assert current_node       instanceof FlatSESEExitNode;
2166           FlatSESEEnterNode fsen = (FlatSESEEnterNode) first.getPrev( 0 );
2167           FlatSESEExitNode  fsxn = (FlatSESEExitNode)  current_node;
2168           assert fsen.getFlatExit().equals( fsxn );
2169           assert fsxn.getFlatEnter().equals( fsen );
2170         }
2171         if (current_node.kind()!=FKind.FlatReturnNode) {
2172       if(state.MGC) {
2173         // TODO add version for normal Java later
2174       if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) {
2175         // a static block, check if it has been executed
2176         output.println("  global_defs_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;");
2177         output.println("");
2178       }
2179       }
2180           output.println("   return;");
2181         }
2182         current_node=null;
2183       } else if(current_node.numNext()==1) {
2184         FlatNode nextnode;
2185         if (state.OOOJAVA && 
2186             current_node.kind()==FKind.FlatSESEEnterNode
2187            ) {
2188           FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node;
2189           generateFlatNode(fm, lb, current_node, output);
2190           nextnode=fsen.getFlatExit().getNext(0);
2191         } else if (state.DELAYCOMP) {
2192           boolean specialprimitive=false;
2193           //skip literals...no need to add extra overhead
2194           if (storeset!=null&&storeset.contains(current_node)&&current_node.kind()==FKind.FlatLiteralNode) {
2195             TypeDescriptor typedesc=((FlatLiteralNode)current_node).getType();
2196             if (!typedesc.isClass()&&!typedesc.isArray()) {
2197               specialprimitive=true;
2198             }
2199           }
2200
2201           if (genset==null||genset.contains(current_node)||specialprimitive)
2202             generateFlatNode(fm, lb, current_node, output);
2203           if (state.STMARRAY&&!state.DUALVIEW&&refset!=null&&refset.contains(current_node)) {
2204             //need to acquire lock
2205             handleArrayDeref(fm, lb, current_node, output, firstpass);
2206           }
2207           if (storeset!=null&&storeset.contains(current_node)&&!specialprimitive) {
2208             TempDescriptor wrtmp=current_node.writesTemps()[0];
2209             if (firstpass) {
2210               //need to store value written by previous node
2211               if (wrtmp.getType().isPtr()) {
2212                 //only lock the objects that may actually need locking
2213                 if (recorddc.getNeedTrans(lb, current_node)&&
2214                     (!state.STMARRAY||state.DUALVIEW||!wrtmp.getType().isArray()||
2215                      wrtmp.getType().getSymbol().equals(TypeUtil.ObjectClass))) {
2216                   output.println("STOREPTR("+generateTemp(fm, wrtmp,lb)+");/* "+current_node.nodeid+" */");
2217                 } else {
2218                   output.println("STOREPTRNOLOCK("+generateTemp(fm, wrtmp,lb)+");/* "+current_node.nodeid+" */");
2219                 }
2220               } else {
2221                 output.println("STORE"+wrtmp.getType().getSafeDescriptor()+"("+generateTemp(fm, wrtmp, lb)+");/* "+current_node.nodeid+" */");
2222               }
2223             } else {
2224               //need to read value read by previous node
2225               if (wrtmp.getType().isPtr()) {
2226                 output.println("RESTOREPTR("+generateTemp(fm, wrtmp,lb)+");/* "+current_node.nodeid+" */");
2227               } else {
2228                 output.println("RESTORE"+wrtmp.getType().getSafeDescriptor()+"("+generateTemp(fm, wrtmp, lb)+"); /* "+current_node.nodeid+" */");               
2229               }
2230             }
2231           }
2232           nextnode=current_node.getNext(0);
2233         } else {
2234           output.print("   ");
2235           generateFlatNode(fm, lb, current_node, output);
2236           nextnode=current_node.getNext(0);
2237         }
2238         if (visited.contains(nextnode)) {
2239           output.println("goto L"+nodetolabel.get(nextnode)+";");
2240           current_node=null;
2241         } else 
2242           current_node=nextnode;
2243       } else if (current_node.numNext()==2) {
2244         /* Branch */
2245         if (state.DELAYCOMP) {
2246           boolean computeside=false;
2247           if (firstpass) {
2248             //need to record which way it should go
2249             if (genset==null||genset.contains(current_node)) {
2250               if (storeset!=null&&storeset.contains(current_node)) {
2251                 //need to store which way branch goes
2252                 generateStoreFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
2253               } else
2254                 generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
2255             } else {
2256               //which side to execute
2257               computeside=true;
2258             }
2259           } else {
2260             if (genset.contains(current_node)) {
2261               generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);             
2262             } else if (storeset.contains(current_node)) {
2263               //need to do branch
2264               branchanalysis.generateGroupCode(current_node, output, nodetolabel);
2265             } else {
2266               //which side to execute
2267               computeside=true;
2268             }
2269           }
2270           if (computeside) {
2271             Set<FlatNode> leftset=DelayComputation.getNext(current_node, 0, unionset, lb,locality, true);
2272             int branch=0;
2273             if (leftset.size()==0)
2274               branch=1;
2275             if (visited.contains(current_node.getNext(branch))) {
2276               //already visited -- build jump
2277               output.println("goto L"+nodetolabel.get(current_node.getNext(branch))+";");
2278               current_node=null;
2279             } else {
2280               current_node=current_node.getNext(branch);
2281             }
2282           } else {
2283             if (!visited.contains(current_node.getNext(1)))
2284               tovisit.add(current_node.getNext(1));
2285             if (visited.contains(current_node.getNext(0))) {
2286               output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
2287               current_node=null;
2288             } else 
2289               current_node=current_node.getNext(0);
2290           }
2291         } else {
2292           output.print("   ");  
2293           generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
2294           if (!visited.contains(current_node.getNext(1)))
2295             tovisit.add(current_node.getNext(1));
2296           if (visited.contains(current_node.getNext(0))) {
2297             output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
2298             current_node=null;
2299           } else 
2300             current_node=current_node.getNext(0);
2301         }
2302       } else throw new Error();
2303     }
2304   }
2305
2306   protected void handleArrayDeref(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output, boolean firstpass) {
2307     if (fn.kind()==FKind.FlatSetElementNode) {
2308       FlatSetElementNode fsen=(FlatSetElementNode) fn;
2309       String dst=generateTemp(fm, fsen.getDst(), lb);
2310       String src=generateTemp(fm, fsen.getSrc(), lb);
2311       String index=generateTemp(fm, fsen.getIndex(), lb);      
2312       TypeDescriptor elementtype=fsen.getDst().getType().dereference();
2313       String type="";
2314       if (elementtype.isArray()||elementtype.isClass())
2315         type="void *";
2316       else
2317         type=elementtype.getSafeSymbol()+" ";
2318       if (firstpass) {
2319         output.println("STOREARRAY("+dst+","+index+","+type+")");
2320       } else {
2321         output.println("{");
2322         output.println("  struct ArrayObject *array;");
2323         output.println("  int index;");
2324         output.println("  RESTOREARRAY(array,index);");
2325         output.println("  (("+type+"*)(((char *)&array->___length___)+sizeof(int)))[index]="+src+";");
2326         output.println("}");
2327       }
2328     } else if (fn.kind()==FKind.FlatElementNode) {
2329       FlatElementNode fen=(FlatElementNode) fn;
2330       String src=generateTemp(fm, fen.getSrc(), lb);
2331       String index=generateTemp(fm, fen.getIndex(), lb);
2332       TypeDescriptor elementtype=fen.getSrc().getType().dereference();
2333       String dst=generateTemp(fm, fen.getDst(), lb);
2334       String type="";
2335       if (elementtype.isArray()||elementtype.isClass())
2336         type="void *";
2337       else
2338         type=elementtype.getSafeSymbol()+" ";
2339       if (firstpass) {
2340         output.println("STOREARRAY("+src+","+index+","+type+")");
2341       } else {
2342         output.println("{");
2343         output.println("  struct ArrayObject *array;");
2344         output.println("  int index;");
2345         output.println("  RESTOREARRAY(array,index);");
2346         output.println("  "+dst+"=(("+type+"*)(((char *)&array->___length___)+sizeof(int)))[index];");
2347         output.println("}");
2348       }
2349     }
2350   }
2351   /** Special label assignment for delaycomputation */
2352   protected Hashtable<FlatNode, Integer> dcassignLabels(FlatNode first, Set<FlatNode> lastset) {
2353     HashSet tovisit=new HashSet();
2354     HashSet visited=new HashSet();
2355     int labelindex=0;
2356     Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
2357
2358     //Label targets of branches
2359     Set<FlatNode> targets=branchanalysis.getTargets();
2360     for(Iterator<FlatNode> it=targets.iterator();it.hasNext();) {
2361       nodetolabel.put(it.next(), new Integer(labelindex++));
2362     }
2363
2364
2365     tovisit.add(first);
2366     /*Assign labels first.  A node needs a label if the previous
2367      * node has two exits or this node is a join point. */
2368
2369     while(!tovisit.isEmpty()) {
2370       FlatNode fn=(FlatNode)tovisit.iterator().next();
2371       tovisit.remove(fn);
2372       visited.add(fn);
2373
2374
2375       if(lastset!=null&&lastset.contains(fn)) {
2376         // if last is not null and matches, don't go 
2377         // any further for assigning labels
2378         continue;
2379       }
2380
2381       for(int i=0; i<fn.numNext(); i++) {
2382         FlatNode nn=fn.getNext(i);
2383
2384         if(i>0) {
2385           //1) Edge >1 of node
2386           nodetolabel.put(nn,new Integer(labelindex++));
2387         }
2388         if (!visited.contains(nn)&&!tovisit.contains(nn)) {
2389           tovisit.add(nn);
2390         } else {
2391           //2) Join point
2392           nodetolabel.put(nn,new Integer(labelindex++));
2393         }
2394       }
2395     }
2396     return nodetolabel;
2397
2398   }
2399
2400   protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first) {
2401     return assignLabels(first, null);
2402   }
2403
2404   protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first, Set<FlatNode> lastset) {
2405     HashSet tovisit=new HashSet();
2406     HashSet visited=new HashSet();
2407     int labelindex=0;
2408     Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
2409     tovisit.add(first);
2410
2411     /*Assign labels first.  A node needs a label if the previous
2412      * node has two exits or this node is a join point. */
2413
2414     while(!tovisit.isEmpty()) {
2415       FlatNode fn=(FlatNode)tovisit.iterator().next();
2416       tovisit.remove(fn);
2417       visited.add(fn);
2418
2419
2420       if(lastset!=null&&lastset.contains(fn)) {
2421         // if last is not null and matches, don't go 
2422         // any further for assigning labels
2423         continue;
2424       }
2425
2426       for(int i=0; i<fn.numNext(); i++) {
2427         FlatNode nn=fn.getNext(i);
2428
2429         if(i>0) {
2430           //1) Edge >1 of node
2431           nodetolabel.put(nn,new Integer(labelindex++));
2432         }
2433         if (!visited.contains(nn)&&!tovisit.contains(nn)) {
2434           tovisit.add(nn);
2435         } else {
2436           //2) Join point
2437           nodetolabel.put(nn,new Integer(labelindex++));
2438         }
2439       }
2440     }
2441     return nodetolabel;
2442   }
2443
2444
2445   /** Generate text string that corresponds to the TempDescriptor td. */
2446   protected String generateTemp(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
2447     MethodDescriptor md=fm.getMethod();
2448     TaskDescriptor task=fm.getTask();
2449     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
2450
2451     if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
2452       return td.getSafeSymbol();
2453     }
2454
2455     if (objecttemps.isLocalPtr(td)) {
2456       return localsprefixderef+td.getSafeSymbol();
2457     }
2458
2459     if (objecttemps.isParamPtr(td)) {
2460       return paramsprefix+"->"+td.getSafeSymbol();
2461     }
2462
2463     throw new Error();
2464   }
2465
2466
2467
2468   protected void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
2469
2470
2471     additionalCodePreNode( fm, lb, fn, output );
2472
2473
2474     switch(fn.kind()) {
2475     case FKind.FlatAtomicEnterNode:
2476       generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
2477       break;
2478
2479     case FKind.FlatAtomicExitNode:
2480       generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
2481       break;
2482
2483     case FKind.FlatInstanceOfNode:
2484       generateFlatInstanceOfNode(fm, lb, (FlatInstanceOfNode)fn, output);
2485       break;
2486
2487     case FKind.FlatSESEEnterNode:
2488       generateFlatSESEEnterNode(fm, lb, (FlatSESEEnterNode)fn, output);
2489       break;
2490
2491     case FKind.FlatSESEExitNode:
2492       generateFlatSESEExitNode(fm, lb, (FlatSESEExitNode)fn, output);
2493       break;
2494       
2495     case FKind.FlatWriteDynamicVarNode:
2496       generateFlatWriteDynamicVarNode(fm, lb, (FlatWriteDynamicVarNode)fn, output);
2497       break;
2498
2499     case FKind.FlatGlobalConvNode:
2500       generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output);
2501       break;
2502
2503     case FKind.FlatTagDeclaration:
2504       generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output);
2505       break;
2506
2507     case FKind.FlatCall:
2508       generateFlatCall(fm, lb, (FlatCall) fn,output);
2509       break;
2510
2511     case FKind.FlatFieldNode:
2512       generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
2513       break;
2514
2515     case FKind.FlatElementNode:
2516       generateFlatElementNode(fm, lb, (FlatElementNode) fn,output);
2517       break;
2518
2519     case FKind.FlatSetElementNode:
2520       generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output);
2521       break;
2522
2523     case FKind.FlatSetFieldNode:
2524       generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
2525       break;
2526
2527     case FKind.FlatNew:
2528       generateFlatNew(fm, lb, (FlatNew) fn,output);
2529       break;
2530
2531     case FKind.FlatOpNode:
2532       generateFlatOpNode(fm, lb, (FlatOpNode) fn,output);
2533       break;
2534
2535     case FKind.FlatCastNode:
2536       generateFlatCastNode(fm, lb, (FlatCastNode) fn,output);
2537       break;
2538
2539     case FKind.FlatLiteralNode:
2540       generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output);
2541       break;
2542
2543     case FKind.FlatReturnNode:
2544       generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output);
2545       break;
2546
2547     case FKind.FlatNop:
2548       output.println("/* nop */");
2549       break;
2550
2551     case FKind.FlatGenReachNode:
2552       // this node is just for generating a reach graph
2553       // in disjointness analysis at a particular program point
2554       break;
2555
2556     case FKind.FlatExit:
2557       output.println("/* exit */");
2558       break;
2559
2560     case FKind.FlatBackEdge:
2561       if (state.SINGLETM&&state.SANDBOX&&(locality.getAtomic(lb).get(fn).intValue()>0)) {
2562         output.println("if (unlikely((--transaction_check_counter)<=0)) checkObjects();");
2563       }
2564       if(state.DSM&&state.SANDBOX&&(locality.getAtomic(lb).get(fn).intValue()>0)) {
2565         output.println("if (unlikely((--transaction_check_counter)<=0)) checkObjects();");
2566       }
2567       if (((state.OOOJAVA||state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC)
2568           || (this.state.MULTICOREGC)) {
2569         if(state.DSM&&locality.getAtomic(lb).get(fn).intValue()>0) {
2570           output.println("if (needtocollect) checkcollect2("+localsprefixaddr+");");
2571         } else if(this.state.MULTICOREGC) {
2572           output.println("if (gcflag) gc("+localsprefixaddr+");");
2573         } else {
2574           output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
2575         }
2576       } else
2577         output.println("/* nop */");
2578       break;
2579
2580     case FKind.FlatCheckNode:
2581       generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output);
2582       break;
2583
2584     case FKind.FlatFlagActionNode:
2585       generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
2586       break;
2587
2588     case FKind.FlatPrefetchNode:
2589       generateFlatPrefetchNode(fm,lb, (FlatPrefetchNode) fn, output);
2590       break;
2591
2592     case FKind.FlatOffsetNode:
2593       generateFlatOffsetNode(fm, lb, (FlatOffsetNode)fn, output);
2594       break;
2595
2596     default:
2597       throw new Error();
2598     }
2599
2600
2601     additionalCodePostNode( fm, lb, fn, output );
2602   }
2603
2604   public void generateFlatOffsetNode(FlatMethod fm, LocalityBinding lb, FlatOffsetNode fofn, PrintWriter output) {
2605     output.println("/* FlatOffsetNode */");
2606     FieldDescriptor fd=fofn.getField();
2607     output.println(generateTemp(fm, fofn.getDst(),lb)+ " = (short)(int) (&((struct "+fofn.getClassType().getSafeSymbol() +" *)0)->"+ 
2608                                                                          fd.getSafeSymbol()+");");
2609     output.println("/* offset */");
2610   }
2611
2612   public void generateFlatPrefetchNode(FlatMethod fm, LocalityBinding lb, FlatPrefetchNode fpn, PrintWriter output) {
2613     if (state.PREFETCH) {
2614       Vector oids = new Vector();
2615       Vector fieldoffset = new Vector();
2616       Vector endoffset = new Vector();
2617       int tuplecount = 0;        //Keeps track of number of prefetch tuples that need to be generated
2618       for(Iterator it = fpn.hspp.iterator(); it.hasNext();) {
2619         PrefetchPair pp = (PrefetchPair) it.next();
2620         Integer statusbase = locality.getNodePreTempInfo(lb,fpn).get(pp.base);
2621         /* Find prefetches that can generate oid */
2622         if(statusbase == LocalityAnalysis.GLOBAL) {
2623           generateTransCode(fm, lb, pp, oids, fieldoffset, endoffset, tuplecount, locality.getAtomic(lb).get(fpn).intValue()>0, false);
2624           tuplecount++;
2625         } else if (statusbase == LocalityAnalysis.LOCAL) {
2626           generateTransCode(fm,lb,pp,oids,fieldoffset,endoffset,tuplecount,false,true);
2627         } else {
2628           continue;
2629         }
2630       }
2631       if (tuplecount==0)
2632         return;
2633       System.out.println("Adding prefetch "+fpn+ " to method:" +fm);
2634       output.println("{");
2635       output.println("/* prefetch */");
2636       output.println("/* prefetchid_" + fpn.siteid + " */");
2637       output.println("void * prefptr;");
2638       output.println("int tmpindex;");
2639
2640       output.println("if((evalPrefetch["+fpn.siteid+"].operMode) || (evalPrefetch["+fpn.siteid+"].retrycount <= 0)) {");
2641       /*Create C code for oid array */
2642       output.print("   unsigned int oidarray_[] = {");
2643       boolean needcomma=false;
2644       for (Iterator it = oids.iterator(); it.hasNext();) {
2645         if (needcomma)
2646           output.print(", ");
2647         output.print(it.next());
2648         needcomma=true;
2649       }
2650       output.println("};");
2651
2652       /*Create C code for endoffset values */
2653       output.print("   unsigned short endoffsetarry_[] = {");
2654       needcomma=false;
2655       for (Iterator it = endoffset.iterator(); it.hasNext();) {
2656         if (needcomma)
2657           output.print(", ");
2658         output.print(it.next());
2659         needcomma=true;
2660       }
2661       output.println("};");
2662
2663       /*Create C code for Field Offset Values */
2664       output.print("   short fieldarry_[] = {");
2665       needcomma=false;
2666       for (Iterator it = fieldoffset.iterator(); it.hasNext();) {
2667         if (needcomma)
2668           output.print(", ");
2669         output.print(it.next());
2670         needcomma=true;
2671       }
2672       output.println("};");
2673       /* make the prefetch call to Runtime */
2674       output.println("   if(!evalPrefetch["+fpn.siteid+"].operMode) {");
2675       output.println("     evalPrefetch["+fpn.siteid+"].retrycount = RETRYINTERVAL;");
2676       output.println("   }");
2677       output.println("   prefetch("+fpn.siteid+" ,"+tuplecount+", oidarray_, endoffsetarry_, fieldarry_);");
2678       output.println(" } else {");
2679       output.println("   evalPrefetch["+fpn.siteid+"].retrycount--;");
2680       output.println(" }");
2681       output.println("}");
2682     }
2683   }
2684
2685   public void generateTransCode(FlatMethod fm, LocalityBinding lb,PrefetchPair pp, Vector oids, Vector fieldoffset, Vector endoffset, int tuplecount, boolean inside, boolean localbase) {
2686     short offsetcount = 0;
2687     int breakindex=0;
2688     if (inside) {
2689       breakindex=1;
2690     } else if (localbase) {
2691       for(; breakindex<pp.desc.size(); breakindex++) {
2692         Descriptor desc=pp.getDescAt(breakindex);
2693         if (desc instanceof FieldDescriptor) {
2694           FieldDescriptor fd=(FieldDescriptor)desc;
2695           if (fd.isGlobal()) {
2696             break;
2697           }
2698         }
2699       }
2700       breakindex++;
2701     }
2702
2703     if (breakindex>pp.desc.size())     //all local
2704       return;
2705
2706     TypeDescriptor lasttype=pp.base.getType();
2707     String basestr=generateTemp(fm, pp.base, lb);
2708     String teststr="";
2709     boolean maybenull=fm.getMethod().isStatic()||
2710                        !pp.base.equals(fm.getParameter(0));
2711
2712     for(int i=0; i<breakindex; i++) {
2713       String indexcheck="";
2714
2715       Descriptor desc=pp.getDescAt(i);
2716       if (desc instanceof FieldDescriptor) {
2717         FieldDescriptor fd=(FieldDescriptor)desc;
2718         if (maybenull) {
2719           if (!teststr.equals(""))
2720             teststr+="&&";
2721           teststr+="((prefptr="+basestr+")!=NULL)";
2722           basestr="((struct "+lasttype.getSafeSymbol()+" *)prefptr)->"+
2723                         fd.getSafeSymbol();
2724         } else {
2725           basestr=basestr+"->"+
2726                         fd.getSafeSymbol();
2727           maybenull=true;
2728         }
2729         lasttype=fd.getType();
2730       } else {
2731         IndexDescriptor id=(IndexDescriptor)desc;
2732         indexcheck="((tmpindex=";
2733         for(int j=0; j<id.tddesc.size(); j++) {
2734           indexcheck+=generateTemp(fm, id.getTempDescAt(j), lb)+"+";
2735         }
2736         indexcheck+=id.offset+")>=0)&(tmpindex<((struct ArrayObject *)prefptr)->___length___)";
2737
2738         if (!teststr.equals(""))
2739           teststr+="&&";
2740         teststr+="((prefptr="+basestr+")!= NULL) &&"+indexcheck;
2741         basestr="((void **)(((char *) &(((struct ArrayObject *)prefptr)->___length___))+sizeof(int)))[tmpindex]";
2742         maybenull=true;
2743         lasttype=lasttype.dereference();
2744       }
2745     }
2746
2747     String oid;
2748     if (teststr.equals("")) {
2749       oid="((unsigned int)"+basestr+")";
2750     } else {
2751       oid="((unsigned int)(("+teststr+")?"+basestr+":NULL))";
2752     }
2753     oids.add(oid);
2754
2755     for(int i = breakindex; i < pp.desc.size(); i++) {
2756       String newfieldoffset;
2757       Object desc = pp.getDescAt(i);
2758       if(desc instanceof FieldDescriptor) {
2759         FieldDescriptor fd=(FieldDescriptor)desc;
2760         newfieldoffset = new String("(unsigned int)(&(((struct "+ lasttype.getSafeSymbol()+" *)0)->"+ fd.getSafeSymbol()+ "))");
2761         lasttype=fd.getType();
2762       } else {
2763         newfieldoffset = "";
2764         IndexDescriptor id=(IndexDescriptor)desc;
2765         for(int j = 0; j < id.tddesc.size(); j++) {
2766           newfieldoffset += generateTemp(fm, id.getTempDescAt(j), lb) + "+";
2767         }
2768         newfieldoffset += id.offset.toString();
2769         lasttype=lasttype.dereference();
2770       }
2771       fieldoffset.add(newfieldoffset);
2772     }
2773
2774     int base=(tuplecount>0) ? ((Short)endoffset.get(tuplecount-1)).intValue() : 0;
2775     base+=pp.desc.size()-breakindex;
2776     endoffset.add(new Short((short)base));
2777   }
2778
2779
2780
2781   public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) {
2782     if (lb!=fgcn.getLocality())
2783       return;
2784     /* Have to generate flat globalconv */
2785     if (fgcn.getMakePtr()) {
2786       if (state.DSM) {
2787            output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
2788       } else {
2789         if ((dc==null)||!state.READSET&&dc.getNeedTrans(lb, fgcn)||state.READSET&&dc.getNeedWriteTrans(lb, fgcn)) {
2790           //need to do translation
2791           output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+", (void *)("+localsprefixaddr+"));");
2792         } else if (state.READSET&&dc.getNeedTrans(lb, fgcn)) {
2793           if (state.HYBRID&&delaycomp.getConv(lb).contains(fgcn)) {
2794             output.println("TRANSREADRDFISSION("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+");");
2795           } else
2796             output.println("TRANSREADRD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+");");
2797         }
2798       }
2799     } else {
2800       /* Need to convert to OID */
2801       if ((dc==null)||dc.getNeedSrcTrans(lb,fgcn)) {
2802         if (fgcn.doConvert()||(delaycomp!=null&&delaycomp.needsFission(lb, fgcn.getAtomicEnter())&&atomicmethodmap.get(fgcn.getAtomicEnter()).reallivein.contains(fgcn.getSrc()))) {
2803           output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
2804         } else {
2805           output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=NULL;");
2806         }
2807       }
2808     }
2809   }
2810
2811   public void generateFlatInstanceOfNode(FlatMethod fm,  LocalityBinding lb, FlatInstanceOfNode fion, PrintWriter output) {
2812     int type;
2813     if (fion.getType().isArray()) {
2814       type=state.getArrayNumber(fion.getType())+state.numClasses();
2815     } else {
2816       type=fion.getType().getClassDesc().getId();
2817     }
2818
2819     if (fion.getType().getSymbol().equals(TypeUtil.ObjectClass))
2820       output.println(generateTemp(fm, fion.getDst(), lb)+"=1;");
2821     else
2822       output.println(generateTemp(fm, fion.getDst(), lb)+"=instanceof("+generateTemp(fm,fion.getSrc(),lb)+","+type+");");
2823   }
2824
2825   int sandboxcounter=0;
2826   public void generateFlatAtomicEnterNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
2827     /* Check to see if we need to generate code for this atomic */
2828     if (locality==null) {
2829       if (GENERATEPRECISEGC) {
2830         output.println("if (pthread_mutex_trylock(&atomiclock)!=0) {");
2831         output.println("stopforgc((struct garbagelist *) &___locals___);");
2832         output.println("pthread_mutex_lock(&atomiclock);");
2833         output.println("restartaftergc();");
2834         output.println("}");
2835       } else {
2836         output.println("pthread_mutex_lock(&atomiclock);");
2837       }
2838       return;
2839     }
2840
2841     if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
2842       return;
2843
2844
2845     if (state.SANDBOX) {
2846       outsandbox.println("int atomiccounter"+sandboxcounter+"=LOW_CHECK_FREQUENCY;");
2847       output.println("counter_reset_pointer=&atomiccounter"+sandboxcounter+";");
2848     }
2849
2850     if (state.DELAYCOMP&&delaycomp.needsFission(lb, faen)) {
2851       AtomicRecord ar=atomicmethodmap.get(faen);
2852       //copy in
2853       for(Iterator<TempDescriptor> tmpit=ar.livein.iterator();tmpit.hasNext();) {
2854         TempDescriptor tmp=tmpit.next();
2855         output.println("primitives_"+ar.name+"."+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
2856       }
2857
2858       //copy outs that depend on path
2859       for(Iterator<TempDescriptor> tmpit=ar.liveoutvirtualread.iterator();tmpit.hasNext();) {
2860         TempDescriptor tmp=tmpit.next();
2861         if (!ar.livein.contains(tmp))
2862           output.println("primitives_"+ar.name+"."+tmp.getSafeSymbol()+"="+tmp.getSafeSymbol()+";");
2863       }
2864     }
2865
2866     /* Backup the temps. */
2867     for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
2868       TempDescriptor tmp=tmpit.next();
2869       output.println(generateTemp(fm, backuptable.get(lb).get(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
2870     }
2871
2872     output.println("goto transstart"+faen.getIdentifier()+";");
2873
2874     /******* Print code to retry aborted transaction *******/
2875     output.println("transretry"+faen.getIdentifier()+":");
2876
2877     /* Restore temps */
2878     for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
2879       TempDescriptor tmp=tmpit.next();
2880       output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(lb).get(tmp),lb)+";");
2881     }
2882
2883     if (state.DSM) {
2884       /********* Need to revert local object store ********/
2885       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2886
2887       output.println("while ("+revertptr+") {");
2888       output.println("struct ___Object___ * tmpptr;");
2889       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
2890       output.println("REVERT_OBJ("+revertptr+");");
2891       output.println(revertptr+"=tmpptr;");
2892       output.println("}");
2893     }
2894     /******* Tell the runtime to start the transaction *******/
2895
2896     output.println("transstart"+faen.getIdentifier()+":");
2897     if (state.SANDBOX) {
2898       output.println("transaction_check_counter=*counter_reset_pointer;");
2899       sandboxcounter++;
2900     }
2901     output.println("transStart();");
2902
2903     if (state.ABORTREADERS||state.SANDBOX) {
2904       if (state.SANDBOX)
2905         output.println("abortenabled=1;");
2906       output.println("if (_setjmp(aborttrans)) {");
2907       output.println("  goto transretry"+faen.getIdentifier()+"; }");
2908     }
2909   }
2910
2911   public void generateFlatAtomicExitNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
2912     /* Check to see if we need to generate code for this atomic */
2913     if (locality==null) {
2914       output.println("pthread_mutex_unlock(&atomiclock);");
2915       return;
2916     }
2917     if (locality.getAtomic(lb).get(faen).intValue()>0)
2918       return;
2919     //store the revert list before we lose the transaction object
2920     
2921     if (state.DSM) {
2922       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2923       output.println(revertptr+"=revertlist;");
2924       output.println("if (transCommit()) {");
2925       output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
2926       output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
2927       output.println("} else {");
2928       /* Need to commit local object store */
2929       output.println("while ("+revertptr+") {");
2930       output.println("struct ___Object___ * tmpptr;");
2931       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
2932       output.println("COMMIT_OBJ("+revertptr+");");
2933       output.println(revertptr+"=tmpptr;");
2934       output.println("}");
2935       output.println("}");
2936       return;
2937     }
2938
2939     if (!state.DELAYCOMP) {
2940       //Normal STM stuff
2941       output.println("if (transCommit()) {");
2942       /* Transaction aborts if it returns true */
2943       output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
2944       output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
2945       output.println("}");
2946     } else {
2947       if (delaycomp.optimizeTrans(lb, faen.getAtomicEnter())&&(!state.STMARRAY||state.DUALVIEW))  {
2948         AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
2949         output.println("LIGHTWEIGHTCOMMIT("+ar.name+", &primitives_"+ar.name+", &"+localsprefix+", "+paramsprefix+", transretry"+faen.getAtomicEnter().getIdentifier()+");");
2950         //copy out
2951         for(Iterator<TempDescriptor> tmpit=ar.liveout.iterator();tmpit.hasNext();) {
2952           TempDescriptor tmp=tmpit.next();
2953           output.println(tmp.getSafeSymbol()+"=primitives_"+ar.name+"."+tmp.getSafeSymbol()+";");
2954         }
2955       } else if (delaycomp.needsFission(lb, faen.getAtomicEnter())) {
2956         AtomicRecord ar=atomicmethodmap.get(faen.getAtomicEnter());
2957         //do call
2958         output.println("if (transCommit((void (*)(void *, void *, void *))&"+ar.name+", &primitives_"+ar.name+", &"+localsprefix+", "+paramsprefix+")) {");
2959         output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
2960         output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
2961         output.println("}");
2962         //copy out
2963         output.println("else {");
2964         for(Iterator<TempDescriptor> tmpit=ar.liveout.iterator();tmpit.hasNext();) {
2965           TempDescriptor tmp=tmpit.next();
2966           output.println(tmp.getSafeSymbol()+"=primitives_"+ar.name+"."+tmp.getSafeSymbol()+";");
2967         }
2968         output.println("}");
2969       } else {
2970         output.println("if (transCommit(NULL, NULL, NULL, NULL)) {");
2971         output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
2972         output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
2973         output.println("}");
2974       }
2975     }
2976   }
2977
2978   public void generateFlatSESEEnterNode( FlatMethod fm,  
2979                                          LocalityBinding lb, 
2980                                          FlatSESEEnterNode fsen, 
2981                                          PrintWriter output) {
2982     // if OOOJAVA flag is off, okay that SESE nodes are in IR graph, 
2983     // just skip over them and code generates exactly the same    
2984   }
2985
2986   public void generateFlatSESEExitNode( FlatMethod fm,
2987                                         LocalityBinding lb,
2988                                         FlatSESEExitNode fsexn,
2989                                         PrintWriter output) {
2990     // if OOOJAVA flag is off, okay that SESE nodes are in IR graph, 
2991     // just skip over them and code generates exactly the same 
2992   }
2993  
2994   public void generateFlatWriteDynamicVarNode( FlatMethod fm,  
2995                                                LocalityBinding lb, 
2996                                                FlatWriteDynamicVarNode fwdvn,
2997                                                PrintWriter output
2998                                              ) {
2999     if( !state.OOOJAVA ) {
3000       // should node should not be in an IR graph if the
3001       // OOOJAVA flag is not set
3002       throw new Error("Unexpected presence of FlatWriteDynamicVarNode");
3003     }
3004   }
3005
3006   
3007   private void generateFlatCheckNode(FlatMethod fm,  LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) {
3008     if (state.CONSCHECK) {
3009       String specname=fcn.getSpec();
3010       String varname="repairstate___";
3011       output.println("{");
3012       output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
3013
3014       TempDescriptor[] temps=fcn.getTemps();
3015       String[] vars=fcn.getVars();
3016       for(int i=0; i<temps.length; i++) {
3017         output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i],lb)+";");
3018       }
3019
3020       output.println("if (doanalysis"+specname+"("+varname+")) {");
3021       output.println("free"+specname+"_state("+varname+");");
3022       output.println("} else {");
3023       output.println("/* Bad invariant */");
3024       output.println("free"+specname+"_state("+varname+");");
3025       output.println("abort_task();");
3026       output.println("}");
3027       output.println("}");
3028     }
3029   }
3030
3031   private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
3032
3033     MethodDescriptor md=fc.getMethod();
3034     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? locality.getBinding(lb, fc) : md);
3035     ClassDescriptor cn=md.getClassDesc();
3036     
3037     // if the called method is a static block or a static method or a constructor
3038     // need to check if it can be invoked inside some static block
3039     if(state.MGC) {
3040       // TODO add version for normal Java later
3041     if((md.isStatic() || md.isStaticBlock() || md.isConstructor()) && 
3042         ((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic()))) {
3043       if(!md.isInvokedByStatic()) {
3044         System.err.println("Error: a method that is invoked inside a static block is not tagged!");
3045       }
3046       // is a static block or is invoked in some static block
3047       ClassDescriptor cd = fm.getMethod().getClassDesc();
3048       if(cd == cn) {
3049         // the same class, do nothing
3050         // TODO may want to invoke static field initialization here
3051       } else {
3052         if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
3053           // need to check if the class' static fields have been initialized and/or
3054           // its static blocks have been executed
3055           output.println("#ifdef MGC_STATIC_INIT_CHECK");
3056           output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {");
3057           if(cn.getNumStaticBlocks() != 0) {
3058             MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks");
3059             output.println("  "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
3060           } else {
3061             output.println("  global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;");
3062           }
3063           output.println("}");
3064           output.println("#endif // MGC_STATIC_INIT_CHECK"); 
3065         }
3066       }
3067     }
3068     if((md.getSymbol().equals("MonitorEnter") || md.getSymbol().equals("MonitorExit")) && fc.getThis().getSymbol().equals("classobj")) {
3069       // call MonitorEnter/MonitorExit on a class obj
3070       output.println("       " + cn.getSafeSymbol()+md.getSafeSymbol()+"_"
3071           +md.getSafeMethodDescriptor() + "((struct ___Object___*)(&global_defs_p->" 
3072           + fc.getThis().getType().getClassDesc().getSafeSymbol() +"classobj));");
3073       return;
3074     }
3075     }
3076     
3077     output.println("{");
3078     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3079       if (lb!=null) {
3080         LocalityBinding fclb=locality.getBinding(lb, fc);
3081         output.print("       struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
3082       } else
3083         output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
3084       output.print(objectparams.numPointers());
3085       output.print(", "+localsprefixaddr);
3086       if (md.getThis()!=null) {
3087         output.print(", ");
3088         output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb));
3089       }
3090       if (fc.getThis()!=null&&md.getThis()==null) {
3091         System.out.println("WARNING!!!!!!!!!!!!");
3092         System.out.println("Source code calls static method "+md+" on an object in "+fm.getMethod()+"!");
3093       }
3094
3095
3096       for(int i=0; i<fc.numArgs(); i++) {
3097         Descriptor var=md.getParameter(i);
3098         TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
3099         if (objectparams.isParamPtr(paramtemp)) {
3100           TempDescriptor targ=fc.getArg(i);
3101           output.print(", ");
3102           TypeDescriptor td=md.getParamType(i);
3103           if (td.isTag())
3104             output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
3105           else
3106             output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
3107         }
3108       }
3109       output.println("};");
3110     }
3111     output.print("       ");
3112
3113
3114     if (fc.getReturnTemp()!=null)
3115       output.print(generateTemp(fm,fc.getReturnTemp(),lb)+"=");
3116
3117     /* Do we need to do virtual dispatch? */
3118     if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
3119       //no
3120       if (lb!=null) {
3121         LocalityBinding fclb=locality.getBinding(lb, fc);
3122         output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
3123       } else {
3124         output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
3125       }
3126     } else {
3127       //yes
3128       output.print("((");
3129       if (state.MGC && md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) {
3130         output.print("int ");
3131       } else if (md.getReturnType().isClass()||md.getReturnType().isArray())
3132         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
3133       else
3134         output.print(md.getReturnType().getSafeSymbol()+" ");
3135       output.print("(*)(");
3136
3137       boolean printcomma=false;
3138       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3139         if (lb!=null) {
3140           LocalityBinding fclb=locality.getBinding(lb, fc);
3141           output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
3142         } else
3143           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
3144         printcomma=true;
3145       }
3146
3147       for(int i=0; i<objectparams.numPrimitives(); i++) {
3148         TempDescriptor temp=objectparams.getPrimitive(i);
3149         if (printcomma)
3150           output.print(", ");
3151         printcomma=true;
3152     if (state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
3153       output.print("int ");
3154     } else if (temp.getType().isClass()||temp.getType().isArray())
3155           output.print("struct " + temp.getType().getSafeSymbol()+" * ");
3156         else
3157           output.print(temp.getType().getSafeSymbol());
3158       }
3159
3160
3161       if (lb!=null) {
3162         LocalityBinding fclb=locality.getBinding(lb, fc);
3163         output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])");
3164       } else
3165         output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
3166     }
3167
3168     output.print("(");
3169     boolean needcomma=false;
3170     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3171       output.print("&__parameterlist__");
3172       needcomma=true;
3173     }
3174
3175     if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
3176       if (fc.getThis()!=null) {
3177         TypeDescriptor ptd=null;
3178     if(md.getThis() != null) {
3179       ptd = md.getThis().getType();
3180     } else {
3181       ptd = fc.getThis().getType();
3182     }
3183         if (needcomma)
3184           output.print(",");
3185     if(state.MGC && ptd.isClass() && ptd.getClassDesc().isEnum()) {
3186       // do nothing 
3187     } else if (ptd.isClass()&&!ptd.isArray())
3188           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
3189         output.print(generateTemp(fm,fc.getThis(),lb));
3190         needcomma=true;
3191       }
3192     }
3193
3194     for(int i=0; i<fc.numArgs(); i++) {
3195       Descriptor var=md.getParameter(i);
3196       TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
3197       if (objectparams.isParamPrim(paramtemp)) {
3198         TempDescriptor targ=fc.getArg(i);
3199         if (needcomma)
3200           output.print(", ");
3201
3202         TypeDescriptor ptd=md.getParamType(i);
3203     if (state.MGC && ptd.isClass() && ptd.getClassDesc().isEnum()) {
3204       // do nothing
3205     } else if (ptd.isClass()&&!ptd.isArray())
3206           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
3207         output.print(generateTemp(fm, targ,lb));
3208         needcomma=true;
3209       }
3210     }
3211     output.println(");");
3212     output.println("   }");
3213   }
3214
3215   private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
3216     Set subclasses=typeutil.getSubClasses(thiscd);
3217     if (subclasses==null)
3218       return true;
3219     for(Iterator classit=subclasses.iterator(); classit.hasNext();) {
3220       ClassDescriptor cd=(ClassDescriptor)classit.next();
3221       Set possiblematches=cd.getMethodTable().getSetFromSameScope(md.getSymbol());
3222       for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
3223         MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
3224         if (md.matches(matchmd))
3225           return false;
3226       }
3227     }
3228     return true;
3229   }
3230
3231   private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) {
3232     if (state.SINGLETM) {
3233       //single machine transactional memory case
3234       String field=ffn.getField().getSafeSymbol();
3235       String src=generateTemp(fm, ffn.getSrc(),lb);
3236       String dst=generateTemp(fm, ffn.getDst(),lb);
3237
3238       output.println(dst+"="+ src +"->"+field+ ";");
3239       if (ffn.getField().getType().isPtr()&&locality.getAtomic(lb).get(ffn).intValue()>0&&
3240           locality.getNodePreTempInfo(lb, ffn).get(ffn.getSrc())!=LocalityAnalysis.SCRATCH) {
3241         if ((dc==null)||(!state.READSET&&dc.getNeedTrans(lb, ffn))||
3242             (state.READSET&&dc.getNeedWriteTrans(lb, ffn))) {
3243           output.println("TRANSREAD("+dst+", "+dst+", (void *) (" + localsprefixaddr + "));");
3244         } else if (state.READSET&&dc.getNeedTrans(lb, ffn)) {
3245           if (state.HYBRID&&delaycomp.getConv(lb).contains(ffn)) {
3246             output.println("TRANSREADRDFISSION("+dst+", "+dst+");");
3247           } else
3248             output.println("TRANSREADRD("+dst+", "+dst+");");
3249         }
3250       }
3251     } else if (state.DSM) {
3252       Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
3253       if (status==LocalityAnalysis.GLOBAL) {
3254         String field=ffn.getField().getSafeSymbol();
3255         String src=generateTemp(fm, ffn.getSrc(),lb);
3256         String dst=generateTemp(fm, ffn.getDst(),lb);
3257
3258         if (ffn.getField().getType().isPtr()) {
3259           output.println(dst+"="+ src +"->"+field+ ";");
3260                 output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
3261         } else {
3262           output.println(dst+"="+ src+"->"+field+";");
3263         }
3264       } else if (status==LocalityAnalysis.LOCAL) {
3265         if (ffn.getField().getType().isPtr()&&
3266             ffn.getField().isGlobal()) {
3267           String field=ffn.getField().getSafeSymbol();
3268           String src=generateTemp(fm, ffn.getSrc(),lb);
3269           String dst=generateTemp(fm, ffn.getDst(),lb);
3270           output.println(dst+"="+ src +"->"+field+ ";");
3271           if (locality.getAtomic(lb).get(ffn).intValue()>0)
3272             output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
3273         } else
3274           output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
3275       } else if (status==LocalityAnalysis.EITHER) {
3276         //Code is reading from a null pointer
3277         output.println("if ("+generateTemp(fm, ffn.getSrc(),lb)+") {");
3278         output.println("#ifndef RAW");
3279         output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
3280         output.println("#endif");
3281         //This should throw a suitable null pointer error
3282         output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
3283       } else
3284         throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
3285     } else{
3286       if(state.MGC) {
3287         // TODO add version for normal Java later
3288       if(ffn.getField().isStatic()) {
3289         // static field
3290         if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
3291           // is a static block or is invoked in some static block
3292           ClassDescriptor cd = fm.getMethod().getClassDesc();
3293           ClassDescriptor cn = ffn.getSrc().getType().getClassDesc();
3294           if(cd == cn) {
3295             // the same class, do nothing
3296             // TODO may want to invoke static field initialization here
3297           } else {
3298             if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
3299               // need to check if the class' static fields have been initialized and/or
3300               // its static blocks have been executed
3301               output.println("#ifdef MGC_STATIC_INIT_CHECK");
3302               output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {");
3303               if(cn.getNumStaticBlocks() != 0) {
3304                 MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks");
3305                 output.println("  "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
3306               } else {
3307                 output.println("  global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;");
3308               }
3309               output.println("}");
3310               output.println("#endif // MGC_STATIC_INIT_CHECK");
3311             }
3312           }
3313         }
3314         // redirect to the global_defs_p structure
3315         if((ffn.getField().isStatic()) || (ffn.getSrc().getType().isClassNameRef())) {
3316           // reference to the static field with Class name
3317           output.println(generateTemp(fm, ffn.getDst(),lb)+"=global_defs_p->"+ 
3318               ffn.getField().getClassDescriptor().getSafeSymbol()+ffn.getField().getSafeSymbol()+";");
3319         } else {
3320           output.println(generateTemp(fm, ffn.getDst(),lb)+"=*"+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
3321         }
3322       } else if (ffn.getField().isEnum()) {
3323           // an Enum value, directly replace the field access as int
3324           output.println(generateTemp(fm, ffn.getDst(), lb) + "=" + ffn.getField().enumValue() + ";");
3325           } else {
3326         output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
3327       }
3328     } else {
3329         output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
3330       }
3331     }
3332   }
3333
3334
3335   private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) {
3336     if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
3337       throw new Error("Can't set array length");
3338     if (state.SINGLETM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
3339       //Single Machine Transaction Case
3340       boolean srcptr=fsfn.getSrc().getType().isPtr();
3341       String src=generateTemp(fm,fsfn.getSrc(),lb);
3342       String dst=generateTemp(fm,fsfn.getDst(),lb);
3343       output.println("//"+srcptr+" "+fsfn.getSrc().getType().isNull());
3344       if (srcptr&&!fsfn.getSrc().getType().isNull()) {
3345                                 output.println("{");
3346                                 if ((dc==null)||dc.getNeedSrcTrans(lb, fsfn)&&
3347                                                 locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getSrc())!=LocalityAnalysis.SCRATCH) {
3348                                         output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
3349                                 } else {
3350                                         output.println("INTPTR srcoid=(INTPTR)"+src+";");
3351                                 }
3352       }
3353       if (wb.needBarrier(fsfn)&&
3354           locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getDst())!=LocalityAnalysis.SCRATCH) {
3355                                 if (state.EVENTMONITOR) {
3356                                         output.println("if ("+dst+"->___objstatus___&DIRTY) EVLOGEVENTOBJ(EV_WRITE,"+dst+"->objuid)");
3357                                 }
3358                                 output.println("*((unsigned int *)&("+dst+"->___objstatus___))|=DIRTY;");
3359       }
3360       if (srcptr&!fsfn.getSrc().getType().isNull()) {
3361                                 output.println("*((unsigned INTPTR *)&("+dst+"->"+ 
3362                                                                                          fsfn.getField().getSafeSymbol()+"))=srcoid;");
3363                                 output.println("}");
3364       } else {
3365                                 output.println(dst+"->"+ 
3366                                                                                          fsfn.getField().getSafeSymbol()+"="+ src+";");
3367       }
3368     } else if (state.DSM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
3369       Integer statussrc=locality.getNodePreTempInfo(lb,fsfn).get(fsfn.getSrc());
3370       Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
3371       boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
3372
3373       String src=generateTemp(fm,fsfn.getSrc(),lb);
3374       String dst=generateTemp(fm,fsfn.getDst(),lb);
3375       if (srcglobal) {
3376                                 output.println("{");
3377                                 output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
3378       }
3379       if (statusdst.equals(LocalityAnalysis.GLOBAL)) {
3380         String glbdst=dst;
3381         //mark it dirty
3382         if (wb.needBarrier(fsfn))
3383           output.println("*((unsigned int *)&("+dst+"->___localcopy___))|=DIRTY;");
3384         if (srcglobal) {
3385           output.println("*((unsigned INTPTR *)&("+glbdst+"->"+ 
3386                                                                          fsfn.getField().getSafeSymbol()+"))=srcoid;");
3387         } else
3388           output.println(glbdst+"->"+ 
3389                                                                          fsfn.getField().getSafeSymbol()+"="+ src+";");
3390       } else if (statusdst.equals(LocalityAnalysis.LOCAL)) {
3391         /** Check if we need to copy */
3392         output.println("if(!"+dst+"->"+localcopystr+") {");
3393         /* Link object into list */
3394         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3395         output.println(revertptr+"=revertlist;");
3396         if (GENERATEPRECISEGC || this.state.MULTICOREGC)
3397           output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
3398         else
3399           output.println("COPY_OBJ("+dst+");");
3400         output.println(dst+"->"+nextobjstr+"="+revertptr+";");
3401         output.println("revertlist=(struct ___Object___ *)"+dst+";");
3402         output.println("}");
3403         if (srcglobal)
3404           output.println(dst+"->"+ 
3405                                                                          fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
3406         else
3407           output.println(dst+"->"+ 
3408                                                                          fsfn.getField().getSafeSymbol()+"="+ src+";");
3409       } else if (statusdst.equals(LocalityAnalysis.EITHER)) {
3410         //writing to a null...bad
3411         output.println("if ("+dst+") {");
3412         output.println("printf(\"BIG ERROR 2\\n\");exit(-1);}");
3413         if (srcglobal)
3414           output.println(dst+"->"+ 
3415                                                                          fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
3416         else
3417           output.println(dst+"->"+ 
3418                                                                          fsfn.getField().getSafeSymbol()+"="+ src+";");
3419       }
3420       if (srcglobal) {
3421         output.println("}");
3422       }
3423     } else {
3424       if (state.FASTCHECK) {
3425         String dst=generateTemp(fm, fsfn.getDst(),lb);
3426         output.println("if(!"+dst+"->"+localcopystr+") {");
3427         /* Link object into list */
3428         if (GENERATEPRECISEGC || this.state.MULTICOREGC)
3429           output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
3430         else
3431           output.println("COPY_OBJ("+dst+");");
3432         output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
3433         output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
3434         output.println("}");
3435       }
3436       if(state.MGC) {
3437         // TODO add version for normal Java later
3438       if(fsfn.getField().isStatic()) {
3439         // static field
3440         if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
3441           // is a static block or is invoked in some static block
3442           ClassDescriptor cd = fm.getMethod().getClassDesc();
3443           ClassDescriptor cn = fsfn.getDst().getType().getClassDesc();
3444           if(cd == cn) {
3445             // the same class, do nothing
3446             // TODO may want to invoke static field initialization here
3447           } else {
3448             if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) {
3449               // need to check if the class' static fields have been initialized and/or
3450               // its static blocks have been executed
3451               output.println("#ifdef MGC_STATIC_INIT_CHECK");
3452               output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {");
3453               if(cn.getNumStaticFields() != 0) {
3454                 // TODO add static field initialization here
3455               }
3456               if(cn.getNumStaticBlocks() != 0) {
3457                 MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks");
3458                 output.println("  "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();");
3459               } else {
3460                 output.println("  global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;");
3461               }
3462               output.println("}");
3463               output.println("#endif // MGC_STATIC_INIT_CHECK"); 
3464             }
3465           }
3466         }
3467         // redirect to the global_defs_p structure
3468         if(fsfn.getDst().getType().isClassNameRef()) {
3469           // reference to the static field with Class name 
3470           output.println("global_defs_p->" + 
3471                                                                                                  fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
3472         } else {
3473           output.println("*"+generateTemp(fm, fsfn.getDst(),lb)+"->"+ 
3474                                                                                                  fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
3475         }
3476       } else {
3477         output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ 
3478                                                                                          fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
3479       } 
3480       } else {
3481         output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ 
3482                                                                                          fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
3483       }
3484     }
3485   }
3486
3487   private void generateFlatElementNode(FlatMethod fm, LocalityBinding lb, FlatElementNode fen, PrintWriter output) {
3488     TypeDescriptor elementtype=fen.getSrc().getType().dereference();
3489     String type="";
3490
3491     if (state.MGC && elementtype.isClass() && elementtype.getClassDesc().isEnum()) {
3492       type="int ";
3493     } else if (elementtype.isArray()||elementtype.isClass())
3494       type="void *";
3495     else
3496       type=elementtype.getSafeSymbol()+" ";
3497
3498     if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) {
3499       output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fen.getIndex(),lb)+") >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___))");
3500       output.println("failedboundschk();");
3501     }
3502     if (state.SINGLETM) {
3503       //Single machine transaction case
3504       String dst=generateTemp(fm, fen.getDst(),lb);
3505       if ((!state.STMARRAY)||(!wb.needBarrier(fen))||locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())==LocalityAnalysis.SCRATCH||locality.getAtomic(lb).get(fen).intValue()==0||(state.READSET&&!dc.getNeedGet(lb, fen))) {
3506         output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3507       } else {
3508         output.println("STMGETARRAY("+dst+", "+ generateTemp(fm,fen.getSrc(),lb)+", "+generateTemp(fm, fen.getIndex(),lb)+", "+type+");");
3509       }
3510
3511       if (elementtype.isPtr()&&locality.getAtomic(lb).get(fen).intValue()>0&&
3512           locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())!=LocalityAnalysis.SCRATCH) {
3513         if ((dc==null)||!state.READSET&&dc.getNeedTrans(lb, fen)||state.READSET&&dc.getNeedWriteTrans(lb, fen)) {
3514           output.println("TRANSREAD("+dst+", "+dst+", (void *)(" + localsprefixaddr+"));");
3515         } else if (state.READSET&&dc.getNeedTrans(lb, fen)) {
3516           if (state.HYBRID&&delaycomp.getConv(lb).contains(fen)) {
3517             output.println("TRANSREADRDFISSION("+dst+", "+dst+");");
3518           } else
3519             output.println("TRANSREADRD("+dst+", "+dst+");");
3520         }
3521       }
3522     } else if (state.DSM) {
3523       Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc());
3524       if (status==LocalityAnalysis.GLOBAL) {
3525         String dst=generateTemp(fm, fen.getDst(),lb);
3526         if (elementtype.isPtr()) {
3527           output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3528           output.println("TRANSREAD("+dst+", "+dst+");");
3529         } else {
3530           output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3531         }
3532       } else if (status==LocalityAnalysis.LOCAL) {
3533         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3534       } else if (status==LocalityAnalysis.EITHER) {
3535         //Code is reading from a null pointer
3536         output.println("if ("+generateTemp(fm, fen.getSrc(),lb)+") {");
3537         output.println("#ifndef RAW");
3538         output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
3539         output.println("#endif");
3540         //This should throw a suitable null pointer error
3541         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3542       } else
3543         throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
3544     } else {
3545         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
3546     }
3547   }
3548
3549   private void generateFlatSetElementNode(FlatMethod fm, LocalityBinding lb, FlatSetElementNode fsen, PrintWriter output) {
3550     //TODO: need dynamic check to make sure this assignment is actually legal
3551     //Because Object[] could actually be something more specific...ie. Integer[]
3552
3553     TypeDescriptor elementtype=fsen.getDst().getType().dereference();
3554     String type="";
3555
3556     if (state.MGC && elementtype.isClass() && elementtype.getClassDesc().isEnum()) {
3557       type="int ";
3558     } else if (elementtype.isArray()||elementtype.isClass() || (state.MGC && elementtype.isNull()))
3559       type="void *";
3560     else
3561       type=elementtype.getSafeSymbol()+" ";
3562
3563     if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) {
3564       output.println("if (unlikely(((unsigned int)"+generateTemp(fm, fsen.getIndex(),lb)+") >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___))");
3565       output.println("failedboundschk();");
3566     }
3567
3568     if (state.SINGLETM && locality.getAtomic(lb).get(fsen).intValue()>0) {
3569       //Transaction set element case
3570       if (wb.needBarrier(fsen)&&
3571           locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH) {
3572         output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___objstatus___))|=DIRTY;");
3573       }
3574       if (fsen.getSrc().getType().isPtr()&&!fsen.getSrc().getType().isNull()) {
3575         output.println("{");
3576         String src=generateTemp(fm, fsen.getSrc(), lb);
3577         if ((dc==null)||dc.getNeedSrcTrans(lb, fsen)&&
3578             locality.getNodePreTempInfo(lb, fsen).get(fsen.getSrc())!=LocalityAnalysis.SCRATCH) {
3579           output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
3580         } else {
3581           output.println("INTPTR srcoid=(INTPTR)"+src+";");
3582         }
3583         if (state.STMARRAY&&locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH&&wb.needBarrier(fsen)&&locality.getAtomic(lb).get(fsen).intValue()>0) {
3584           output.println("STMSETARRAY("+generateTemp(fm, fsen.getDst(),lb)+", "+generateTemp(fm, fsen.getIndex(),lb)+", srcoid, INTPTR);");
3585         } else {
3586           output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
3587         }
3588         output.println("}");
3589       } else {
3590         if (state.STMARRAY&&locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH&&wb.needBarrier(fsen)&&locality.getAtomic(lb).get(fsen).intValue()>0) {
3591           output.println("STMSETARRAY("+generateTemp(fm, fsen.getDst(),lb)+", "+generateTemp(fm, fsen.getIndex(),lb)+", "+ generateTemp(fm, fsen.getSrc(), lb) +", "+type+");");
3592         } else {
3593           output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
3594         }
3595       }
3596     } else if (state.DSM && locality.getAtomic(lb).get(fsen).intValue()>0) {
3597       Integer statussrc=locality.getNodePreTempInfo(lb,fsen).get(fsen.getSrc());
3598       Integer statusdst=locality.getNodePreTempInfo(lb,fsen).get(fsen.getDst());
3599       boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
3600       boolean dstglobal=statusdst==LocalityAnalysis.GLOBAL;
3601       boolean dstlocal=(statusdst==LocalityAnalysis.LOCAL)||(statusdst==LocalityAnalysis.EITHER);
3602       
3603       if (dstglobal) {
3604         if (wb.needBarrier(fsen))
3605           output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___localcopy___))|=DIRTY;");
3606       } else if (dstlocal) {
3607         /** Check if we need to copy */
3608         String dst=generateTemp(fm, fsen.getDst(),lb);
3609         output.println("if(!"+dst+"->"+localcopystr+") {");
3610         /* Link object into list */
3611         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3612         output.println(revertptr+"=revertlist;");
3613         if ((GENERATEPRECISEGC) || this.state.MULTICOREGC)
3614         output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
3615         else
3616           output.println("COPY_OBJ("+dst+");");
3617         output.println(dst+"->"+nextobjstr+"="+revertptr+";");
3618         output.println("revertlist=(struct ___Object___ *)"+dst+";");
3619         output.println("}");
3620       } else {
3621         System.out.println("Node: "+fsen);
3622         System.out.println(lb);
3623         System.out.println("statusdst="+statusdst);
3624         System.out.println(fm.printMethod());
3625         throw new Error("Unknown array type");
3626       }
3627       if (srcglobal) {
3628         output.println("{");
3629         String src=generateTemp(fm, fsen.getSrc(), lb);
3630         output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
3631         output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
3632         output.println("}");
3633       } else {
3634         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
3635       }
3636     } else {
3637       if (state.FASTCHECK) {
3638         String dst=generateTemp(fm, fsen.getDst(),lb);
3639         output.println("if(!"+dst+"->"+localcopystr+") {");
3640         /* Link object into list */
3641         if (GENERATEPRECISEGC || this.state.MULTICOREGC)
3642           output.println("COPY_OBJ((struct garbagelist *)"+localsprefixaddr+",(struct ___Object___ *)"+dst+");");
3643         else
3644           output.println("COPY_OBJ("+dst+");");
3645         output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
3646         output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
3647         output.println("}");
3648       }
3649       output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
3650     }
3651   }
3652
3653
3654   protected void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) {
3655     if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
3656       //Stash pointer in case of GC
3657       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3658       output.println(revertptr+"=revertlist;");
3659     }
3660     if (state.SINGLETM) {
3661       if (fn.getType().isArray()) {
3662         int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
3663         if (locality.getAtomic(lb).get(fn).intValue()>0) {
3664           //inside transaction
3665           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarraytrans("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
3666         } else {
3667           //outside transaction
3668           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
3669         }
3670       } else {
3671         if (locality.getAtomic(lb).get(fn).intValue()>0) {
3672           //inside transaction
3673           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newtrans("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
3674         } else {
3675           //outside transaction
3676           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");
3677         }
3678       }
3679     } else if (fn.getType().isArray()) {
3680       int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
3681       if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
3682         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
3683       } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3684         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");                  
3685       } else {
3686         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
3687       }
3688     } else {
3689       if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
3690         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal("+fn.getType().getClassDesc().getId()+");");
3691       } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3692         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");");        
3693       } else {
3694         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
3695       }
3696     }
3697     if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
3698       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3699       String dst=generateTemp(fm,fn.getDst(),lb);
3700       output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
3701       output.println(dst+"->"+nextobjstr+"="+revertptr+";");
3702       output.println("revertlist=(struct ___Object___ *)"+dst+";");
3703     }
3704     if (state.FASTCHECK) {
3705       String dst=generateTemp(fm,fn.getDst(),lb);
3706       output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
3707       output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
3708       output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
3709     }
3710   }
3711
3712   private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) {
3713     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3714       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+localsprefixaddr+", "+state.getTagId(fn.getType())+");");
3715     } else {
3716       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");");
3717     }
3718   }
3719
3720   private void generateFlatOpNode(FlatMethod fm, LocalityBinding lb, FlatOpNode fon, PrintWriter output) {
3721     if (fon.getRight()!=null) {
3722       if (fon.getOp().getOp()==Operation.URIGHTSHIFT) {
3723         if (fon.getLeft().getType().isLong())
3724           output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
3725         else
3726           output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned int)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
3727
3728       } else if (dc!=null) {
3729         output.print(generateTemp(fm, fon.getDest(),lb)+" = (");
3730         if (fon.getLeft().getType().isPtr()&&(fon.getOp().getOp()==Operation.EQUAL||fon.getOp().getOp()==Operation.NOTEQUAL))
3731             output.print("(void *)");
3732         if (dc.getNeedLeftSrcTrans(lb, fon))
3733           output.print("("+generateTemp(fm, fon.getLeft(),lb)+"!=NULL?"+generateTemp(fm, fon.getLeft(),lb)+"->"+oidstr+":NULL)");
3734         else
3735           output.print(generateTemp(fm, fon.getLeft(),lb));
3736         output.print(")"+fon.getOp().toString()+"(");
3737         if (fon.getRight().getType().isPtr()&&(fon.getOp().getOp()==Operation.EQUAL||fon.getOp().getOp()==Operation.NOTEQUAL))
3738             output.print("(void *)");
3739         if (dc.getNeedRightSrcTrans(lb, fon))
3740           output.println("("+generateTemp(fm, fon.getRight(),lb)+"!=NULL?"+generateTemp(fm, fon.getRight(),lb)+"->"+oidstr+":NULL));");
3741         else
3742           output.println(generateTemp(fm,fon.getRight(),lb)+");");
3743       } else
3744         output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";");
3745     } else if (fon.getOp().getOp()==Operation.ASSIGN)
3746       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
3747     else if (fon.getOp().getOp()==Operation.UNARYPLUS)
3748       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
3749     else if (fon.getOp().getOp()==Operation.UNARYMINUS)
3750       output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";");
3751     else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
3752       output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";");
3753     else if (fon.getOp().getOp()==Operation.COMP)
3754       output.println(generateTemp(fm, fon.getDest(),lb)+" = ~"+generateTemp(fm, fon.getLeft(),lb)+";");
3755     else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
3756       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+"->fses==NULL;");
3757     } else
3758       output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";");
3759   }
3760
3761   private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) {
3762     /* TODO: Do type check here */
3763     if (fcn.getType().isArray()) {
3764       output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct ArrayObject *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
3765     } else if (state.MGC && fcn.getType().isClass() && fcn.getType().getClassDesc().isEnum()) {
3766       output.println(generateTemp(fm,fcn.getDst(),lb)+"=(int)"+generateTemp(fm,fcn.getSrc(),lb)+";");
3767     } else if (fcn.getType().isClass())
3768       output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
3769     else
3770       output.println(generateTemp(fm,fcn.getDst(),lb)+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc(),lb)+";");
3771   }
3772
3773   private void generateFlatLiteralNode(FlatMethod fm, LocalityBinding lb, FlatLiteralNode fln, PrintWriter output) {
3774     if (fln.getValue()==null)
3775       output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
3776     else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
3777       if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3778         if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
3779           //Stash pointer in case of GC
3780           String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3781           output.println(revertptr+"=revertlist;");
3782         }
3783         output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString("+localsprefixaddr+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
3784         if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
3785           //Stash pointer in case of GC
3786           String revertptr=generateTemp(fm, reverttable.get(lb),lb);
3787           output.println("revertlist="+revertptr+";");
3788         }
3789       } else {
3790         output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
3791       }
3792     } else if (fln.getType().isBoolean()) {
3793       if (((Boolean)fln.getValue()).booleanValue())
3794         output.println(generateTemp(fm, fln.getDst(),lb)+"=1;");
3795       else
3796         output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
3797     } else if (fln.getType().isChar()) {
3798       String st=FlatLiteralNode.escapeString(fln.getValue().toString());
3799       output.println(generateTemp(fm, fln.getDst(),lb)+"='"+st+"';");
3800     } else if (fln.getType().isLong()) {
3801       output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+"LL;");
3802     } else
3803       output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
3804   }
3805
3806   protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
3807     if(state.MGC) {
3808       // TODO add version for normal Java later
3809     if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) {
3810       // a static block, check if it has been executed
3811       output.println("  global_defs_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;");
3812       output.println("");
3813     }
3814     }
3815     if (frn.getReturnTemp()!=null) {
3816       if (frn.getReturnTemp().getType().isPtr())
3817         output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
3818       else
3819         output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
3820     } else {
3821       output.println("return;");
3822     }
3823   }
3824
3825   protected void generateStoreFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
3826     int left=-1;
3827     int right=-1;
3828     //only record if this group has more than one exit
3829     if (branchanalysis.numJumps(fcb)>1) {
3830       left=branchanalysis.jumpValue(fcb, 0);
3831       right=branchanalysis.jumpValue(fcb, 1);
3832     }
3833     output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") {");
3834     if (right!=-1)
3835       output.println("STOREBRANCH("+right+");");
3836     output.println("goto "+label+";");
3837     output.println("}");
3838     if (left!=-1)
3839       output.println("STOREBRANCH("+left+");");
3840   }
3841
3842   protected void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
3843     output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";");
3844   }
3845
3846   /** This method generates header information for the method or
3847    * task referenced by the Descriptor des. */
3848   private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
3849     generateHeader(fm, lb, des, output, false);
3850   }
3851
3852   private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output, boolean addSESErecord) {
3853     /* Print header */
3854     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
3855     MethodDescriptor md=null;
3856     TaskDescriptor task=null;
3857     if (des instanceof MethodDescriptor)
3858       md=(MethodDescriptor) des;
3859     else
3860       task=(TaskDescriptor) des;
3861
3862     ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
3863
3864     if (md!=null&&md.getReturnType()!=null) {
3865       if (state.MGC && md.getReturnType().isClass() && md.getReturnType().getClassDesc().isEnum()) {
3866         output.print("int ");
3867       } else if (md.getReturnType().isClass()||md.getReturnType().isArray())
3868         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
3869       else
3870         output.print(md.getReturnType().getSafeSymbol()+" ");
3871     } else
3872       //catch the constructor case
3873       output.print("void ");
3874     if (md!=null) {
3875       if (state.DSM||state.SINGLETM) {
3876         output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
3877       } else
3878         output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
3879     } else
3880       output.print(task.getSafeSymbol()+"(");
3881     
3882     boolean printcomma=false;
3883     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
3884       if (md!=null) {
3885         if (state.DSM||state.SINGLETM) {
3886           output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
3887         } else
3888           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
3889       } else
3890         output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
3891       printcomma=true;
3892     }
3893
3894     if (md!=null) {
3895       /* Method */
3896       for(int i=0; i<objectparams.numPrimitives(); i++) {
3897         TempDescriptor temp=objectparams.getPrimitive(i);
3898         if (printcomma)
3899           output.print(", ");
3900         printcomma=true;
3901     if(state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
3902       output.print("int " + temp.getSafeSymbol());
3903     } else if (temp.getType().isClass()||temp.getType().isArray())
3904           output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
3905         else
3906           output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
3907       }
3908       output.println(") {");
3909     } else if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
3910       /* Imprecise Task */
3911       output.println("void * parameterarray[]) {");
3912       /* Unpack variables */
3913       for(int i=0; i<objectparams.numPrimitives(); i++) {
3914         TempDescriptor temp=objectparams.getPrimitive(i);
3915     if(state.MGC && temp.getType().isClass() && temp.getType().getClassDesc().isEnum()) {
3916       output.print("int " + temp.getSafeSymbol() + "=parameterarray["+i+"];");
3917     } else {
3918       output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
3919     }
3920       }
3921       for(int i=0; i<fm.numTags(); i++) {
3922         TempDescriptor temp=fm.getTag(i);
3923         int offset=i+objectparams.numPrimitives();
3924         output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
3925       }
3926
3927       if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
3928         maxtaskparams=objectparams.numPrimitives()+fm.numTags();
3929     } else output.println(") {");
3930   }
3931
3932   public void generateFlatFlagActionNode(FlatMethod fm, LocalityBinding lb, FlatFlagActionNode ffan, PrintWriter output) {
3933     output.println("/* FlatFlagActionNode */");
3934
3935
3936     /* Process tag changes */
3937     Relation tagsettable=new Relation();
3938     Relation tagcleartable=new Relation();
3939
3940     Iterator tagsit=ffan.getTempTagPairs();
3941     while (tagsit.hasNext()) {
3942       TempTagPair ttp=(TempTagPair) tagsit.next();
3943       TempDescriptor objtmp=ttp.getTemp();
3944       TagDescriptor tag=ttp.getTag();
3945       TempDescriptor tagtmp=ttp.getTagTemp();
3946       boolean tagstatus=ffan.getTagChange(ttp);
3947       if (tagstatus) {
3948         tagsettable.put(objtmp, tagtmp);
3949       } else {
3950         tagcleartable.put(objtmp, tagtmp);
3951       }
3952     }
3953
3954
3955     Hashtable flagandtable=new Hashtable();
3956     Hashtable flagortable=new Hashtable();
3957
3958     /* Process flag changes */
3959     Iterator flagsit=ffan.getTempFlagPairs();
3960     while(flagsit.hasNext()) {
3961       TempFlagPair tfp=(TempFlagPair)flagsit.next();
3962       TempDescriptor temp=tfp.getTemp();
3963       Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
3964       FlagDescriptor flag=tfp.getFlag();
3965       if (flag==null) {
3966         //Newly allocate objects that don't set any flags case
3967         if (flagortable.containsKey(temp)) {
3968           throw new Error();
3969         }
3970         int mask=0;
3971         flagortable.put(temp,new Integer(mask));
3972       } else {
3973         int flagid=1<<((Integer)flagtable.get(flag)).intValue();
3974         boolean flagstatus=ffan.getFlagChange(tfp);
3975         if (flagstatus) {
3976           int mask=0;
3977           if (flagortable.containsKey(temp)) {
3978             mask=((Integer)flagortable.get(temp)).intValue();
3979           }
3980           mask|=flagid;
3981           flagortable.put(temp,new Integer(mask));
3982         } else {
3983           int mask=0xFFFFFFFF;
3984           if (flagandtable.containsKey(temp)) {
3985             mask=((Integer)flagandtable.get(temp)).intValue();
3986           }
3987           mask&=(0xFFFFFFFF^flagid);
3988           flagandtable.put(temp,new Integer(mask));
3989         }
3990       }
3991     }
3992
3993
3994     HashSet flagtagset=new HashSet();
3995     flagtagset.addAll(flagortable.keySet());
3996     flagtagset.addAll(flagandtable.keySet());
3997     flagtagset.addAll(tagsettable.keySet());
3998     flagtagset.addAll(tagcleartable.keySet());
3999
4000     Iterator ftit=flagtagset.iterator();
4001     while(ftit.hasNext()) {
4002       TempDescriptor temp=(TempDescriptor)ftit.next();
4003
4004
4005       Set tagtmps=tagcleartable.get(temp);
4006       if (tagtmps!=null) {
4007         Iterator tagit=tagtmps.iterator();
4008         while(tagit.hasNext()) {
4009           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
4010           if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
4011             output.println("tagclear("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
4012           else
4013             output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
4014         }
4015       }
4016
4017       tagtmps=tagsettable.get(temp);
4018       if (tagtmps!=null) {
4019         Iterator tagit=tagtmps.iterator();
4020         while(tagit.hasNext()) {
4021           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
4022           if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC))
4023             output.println("tagset("+localsprefixaddr+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
4024           else
4025             output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
4026         }
4027       }
4028
4029       int ormask=0;
4030       int andmask=0xFFFFFFF;
4031
4032       if (flagortable.containsKey(temp))
4033         ormask=((Integer)flagortable.get(temp)).intValue();
4034       if (flagandtable.containsKey(temp))
4035         andmask=((Integer)flagandtable.get(temp)).intValue();
4036       generateFlagOrAnd(ffan, fm, lb, temp, output, ormask, andmask);
4037       generateObjectDistribute(ffan, fm, lb, temp, output);
4038     }
4039   }
4040
4041   protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
4042                                    PrintWriter output, int ormask, int andmask) {
4043     if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
4044       output.println("flagorandinit("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
4045     } else {
4046       output.println("flagorand("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
4047     }
4048   }
4049
4050   protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp, PrintWriter output) {
4051     output.println("enqueueObject("+generateTemp(fm, temp, lb)+");");
4052   }
4053
4054   void generateOptionalHeader(PrintWriter headers) {
4055
4056     //GENERATE HEADERS
4057     headers.println("#include \"task.h\"\n\n");
4058     headers.println("#ifndef _OPTIONAL_STRUCT_");
4059     headers.println("#define _OPTIONAL_STRUCT_");
4060
4061     //STRUCT PREDICATEMEMBER
4062     headers.println("struct predicatemember{");
4063     headers.println("int type;");
4064     headers.println("int numdnfterms;");
4065     headers.println("int * flags;");
4066     headers.println("int numtags;");
4067     headers.println("int * tags;\n};\n\n");
4068
4069     //STRUCT OPTIONALTASKDESCRIPTOR
4070     headers.println("struct optionaltaskdescriptor{");
4071     headers.println("struct taskdescriptor * task;");
4072     headers.println("int index;");
4073     headers.println("int numenterflags;");
4074     headers.println("int * enterflags;");
4075     headers.println("int numpredicatemembers;");
4076     headers.println("struct predicatemember ** predicatememberarray;");
4077     headers.println("};\n\n");
4078
4079     //STRUCT TASKFAILURE
4080     headers.println("struct taskfailure {");
4081     headers.println("struct taskdescriptor * task;");
4082     headers.println("int index;");
4083     headers.println("int numoptionaltaskdescriptors;");
4084     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
4085
4086     //STRUCT FSANALYSISWRAPPER
4087     headers.println("struct fsanalysiswrapper{");
4088     headers.println("int  flags;");
4089     headers.println("int numtags;");
4090     headers.println("int * tags;");
4091     headers.println("int numtaskfailures;");
4092     headers.println("struct taskfailure ** taskfailurearray;");
4093     headers.println("int numoptionaltaskdescriptors;");
4094     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
4095
4096     //STRUCT CLASSANALYSISWRAPPER
4097     headers.println("struct classanalysiswrapper{");
4098     headers.println("int type;");
4099     headers.println("int numotd;");
4100     headers.println("struct optionaltaskdescriptor ** otdarray;");
4101     headers.println("int numfsanalysiswrappers;");
4102     headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
4103
4104     headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
4105
4106     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
4107     while(taskit.hasNext()) {
4108       TaskDescriptor td=(TaskDescriptor)taskit.next();
4109       headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
4110     }
4111
4112   }
4113
4114   //CHECK OVER THIS -- THERE COULD BE SOME ERRORS HERE
4115   int generateOptionalPredicate(Predicate predicate, OptionalTaskDescriptor otd, ClassDescriptor cdtemp, PrintWriter output) {
4116     int predicateindex = 0;
4117     //iterate through the classes concerned by the predicate
4118     Set c_vard = predicate.vardescriptors;
4119     Hashtable<TempDescriptor, Integer> slotnumber=new Hashtable<TempDescriptor, Integer>();
4120     int current_slot=0;
4121
4122     for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();) {
4123       VarDescriptor vard = (VarDescriptor)vard_it.next();
4124       TypeDescriptor typed = vard.getType();
4125
4126       //generate for flags
4127       HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
4128       output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
4129       int numberterms=0;
4130       if (fen_hashset!=null) {
4131         for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();) {
4132           FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
4133           if (fen!=null) {
4134             DNFFlag dflag=fen.getDNF();
4135             numberterms+=dflag.size();
4136
4137             Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
4138
4139             for(int j=0; j<dflag.size(); j++) {
4140               if (j!=0)
4141                 output.println(",");
4142               Vector term=dflag.get(j);
4143               int andmask=0;
4144               int checkmask=0;
4145               for(int k=0; k<term.size(); k++) {
4146                 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
4147                 FlagDescriptor fd=dfa.getFlag();
4148                 boolean negated=dfa.getNegated();
4149                 int flagid=1<<((Integer)flags.get(fd)).intValue();
4150                 andmask|=flagid;
4151                 if (!negated)
4152                   checkmask|=flagid;
4153               }
4154               output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
4155             }
4156           }
4157         }
4158       }
4159       output.println("};\n");
4160
4161       //generate for tags
4162       TagExpressionList tagel = predicate.tags.get(vard.getSymbol());
4163       output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
4164       int numtags = 0;
4165       if (tagel!=null) {
4166         for(int j=0; j<tagel.numTags(); j++) {
4167           if (j!=0)
4168             output.println(",");
4169           TempDescriptor tmp=tagel.getTemp(j);
4170           if (!slotnumber.containsKey(tmp)) {
4171             Integer slotint=new Integer(current_slot++);
4172             slotnumber.put(tmp,slotint);
4173           }
4174           int slot=slotnumber.get(tmp).intValue();
4175           output.println("/* slot */"+ slot+", /*tagid*/"+state.getTagId(tmp.getTag()));
4176         }
4177         numtags = tagel.numTags();
4178       }
4179       output.println("};");
4180
4181       //store the result into a predicatemember struct
4182       output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
4183       output.println("/*type*/"+typed.getClassDesc().getId()+",");
4184       output.println("/* number of dnf terms */"+numberterms+",");
4185       output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4186       output.println("/* number of tag */"+numtags+",");
4187       output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4188       output.println("};\n");
4189       predicateindex++;
4190     }
4191
4192
4193     //generate an array that stores the entire predicate
4194     output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
4195     for( int j = 0; j<predicateindex; j++) {
4196       if( j != predicateindex-1) output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4197       else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
4198     }
4199     output.println("};\n");
4200     return predicateindex;
4201   }
4202
4203
4204   void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> safeexecution, Hashtable optionaltaskdescriptors) {
4205     generateOptionalHeader(headers);
4206     //GENERATE STRUCTS
4207     output.println("#include \"optionalstruct.h\"\n\n");
4208     output.println("#include \"stdlib.h\"\n");
4209
4210     HashSet processedcd = new HashSet();
4211     int maxotd=0;
4212     Enumeration e = safeexecution.keys();
4213     while (e.hasMoreElements()) {
4214       int numotd=0;
4215       //get the class
4216       ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
4217       Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);       //will be used several times
4218
4219       //Generate the struct of optionals
4220       Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
4221       numotd = c_otd.size();
4222       if(maxotd<numotd) maxotd = numotd;
4223       if( !c_otd.isEmpty() ) {
4224         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
4225           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
4226
4227           //generate the int arrays for the predicate
4228           Predicate predicate = otd.predicate;
4229           int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
4230           TreeSet<Integer> fsset=new TreeSet<Integer>();
4231           //iterate through possible FSes corresponding to
4232           //the state when entering
4233
4234           for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext();) {
4235             FlagState fs = (FlagState)fses.next();
4236             int flagid=0;
4237             for(Iterator flags = fs.getFlags(); flags.hasNext();) {
4238               FlagDescriptor flagd = (FlagDescriptor)flags.next();
4239               int id=1<<((Integer)flaginfo.get(flagd)).intValue();
4240               flagid|=id;
4241             }
4242             fsset.add(new Integer(flagid));
4243             //tag information not needed because tag
4244             //changes are not tolerated.
4245           }
4246
4247           output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
4248           boolean needcomma=false;
4249           for(Iterator<Integer> it=fsset.iterator(); it.hasNext();) {
4250             if(needcomma)
4251               output.print(", ");
4252             output.println(it.next());
4253           }
4254
4255           output.println("};\n");
4256
4257
4258           //generate optionaltaskdescriptor that actually
4259           //includes exit fses, predicate and the task
4260           //concerned
4261           output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
4262           output.println("&task_"+otd.td.getSafeSymbol()+",");
4263           output.println("/*index*/"+otd.getIndex()+",");
4264           output.println("/*number of enter flags*/"+fsset.size()+",");
4265           output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4266           output.println("/*number of members */"+predicateindex+",");
4267           output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4268           output.println("};\n");
4269         }
4270       } else
4271         continue;
4272       // if there are no optionals, there is no need to build the rest of the struct
4273
4274       output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
4275       c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
4276       if( !c_otd.isEmpty() ) {
4277         boolean needcomma=false;
4278         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
4279           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
4280           if(needcomma)
4281             output.println(",");
4282           needcomma=true;
4283           output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
4284         }
4285       }
4286       output.println("};\n");
4287
4288       //get all the possible flagstates reachable by an object
4289       Hashtable hashtbtemp = safeexecution.get(cdtemp);
4290       int fscounter = 0;
4291       TreeSet fsts=new TreeSet(new FlagComparator(flaginfo));
4292       fsts.addAll(hashtbtemp.keySet());
4293       for(Iterator fsit=fsts.iterator(); fsit.hasNext();) {
4294         FlagState fs = (FlagState)fsit.next();
4295         fscounter++;
4296
4297         //get the set of OptionalTaskDescriptors corresponding
4298         HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)hashtbtemp.get(fs);
4299         //iterate through the OptionalTaskDescriptors and
4300         //store the pointers to the optionals struct (see on
4301         //top) into an array
4302
4303         output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
4304         for(Iterator<OptionalTaskDescriptor> mos = ordertd(availabletasks).iterator(); mos.hasNext();) {
4305           OptionalTaskDescriptor mm = mos.next();
4306           if(!mos.hasNext())
4307             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
4308           else
4309             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
4310         }
4311
4312         output.println("};\n");
4313
4314         //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
4315
4316         int flagid=0;
4317         for(Iterator flags = fs.getFlags(); flags.hasNext();) {
4318           FlagDescriptor flagd = (FlagDescriptor)flags.next();
4319           int id=1<<((Integer)flaginfo.get(flagd)).intValue();
4320           flagid|=id;
4321         }
4322
4323         //process tag information
4324
4325         int tagcounter = 0;
4326         boolean first = true;
4327         Enumeration tag_enum = fs.getTags();
4328         output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
4329         while(tag_enum.hasMoreElements()) {
4330           tagcounter++;
4331           TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement();
4332           if(first==true)
4333             first = false;
4334           else
4335             output.println(", ");
4336           output.println("/*tagid*/"+state.getTagId(tagd));
4337         }
4338         output.println("};");
4339
4340         Set<TaskIndex> tiset=sa.getTaskIndex(fs);
4341         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
4342           TaskIndex ti=itti.next();
4343           if (ti.isRuntime())
4344             continue;
4345
4346           Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
4347
4348           output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
4349           boolean needcomma=false;
4350           for(Iterator<OptionalTaskDescriptor> otdit=ordertd(otdset).iterator(); otdit.hasNext();) {
4351             OptionalTaskDescriptor otd=otdit.next();
4352             if(needcomma)
4353               output.print(", ");
4354             needcomma=true;
4355             output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
4356           }
4357           output.println("};");
4358
4359           output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
4360           output.print("&task_"+ti.getTask().getSafeSymbol()+", ");
4361           output.print(ti.getIndex()+", ");
4362           output.print(otdset.size()+", ");
4363           output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
4364           output.println("};");
4365         }
4366
4367         tiset=sa.getTaskIndex(fs);
4368         boolean needcomma=false;
4369         int runtimeti=0;
4370         output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
4371         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
4372           TaskIndex ti=itti.next();
4373           if (ti.isRuntime()) {
4374             runtimeti++;
4375             continue;
4376           }
4377           if (needcomma)
4378             output.print(", ");
4379           needcomma=true;
4380           output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
4381         }
4382         output.println("};\n");
4383
4384         //Store the result in fsanalysiswrapper
4385
4386         output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
4387         output.println("/*flag*/"+flagid+",");
4388         output.println("/* number of tags*/"+tagcounter+",");
4389         output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
4390         output.println("/* numtask failures */"+(tiset.size()-runtimeti)+",");
4391         output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
4392         output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
4393         output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
4394         output.println("};\n");
4395
4396       }
4397
4398       //Build the array of fsanalysiswrappers
4399       output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
4400       boolean needcomma=false;
4401       for(int i = 0; i<fscounter; i++) {
4402         if (needcomma) output.print(",");
4403         output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
4404         needcomma=true;
4405       }
4406       output.println("};");
4407
4408       //Build the classanalysiswrapper referring to the previous array
4409       output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
4410       output.println("/*type*/"+cdtemp.getId()+",");
4411       output.println("/*numotd*/"+numotd+",");
4412       output.println("otdarray"+cdtemp.getSafeSymbol()+",");
4413       output.println("/* number of fsanalysiswrappers */"+fscounter+",");
4414       output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
4415       processedcd.add(cdtemp);
4416     }
4417
4418     //build an array containing every classes for which code has been build
4419     output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
4420     for(int i=0; i<state.numClasses(); i++) {
4421       ClassDescriptor cn=cdarray[i];
4422       if (i>0)
4423         output.print(", ");
4424       if ((cn != null) && (processedcd.contains(cn)))
4425         output.print("&classanalysiswrapper_"+cn.getSafeSymbol());
4426       else
4427         output.print("NULL");
4428     }
4429     output.println("};");
4430
4431     output.println("#define MAXOTD "+maxotd);
4432     headers.println("#endif");
4433   }
4434
4435   public List<OptionalTaskDescriptor> ordertd(Set<OptionalTaskDescriptor> otdset) {
4436     Relation r=new Relation();
4437     for(Iterator<OptionalTaskDescriptor>otdit=otdset.iterator(); otdit.hasNext();) {
4438       OptionalTaskDescriptor otd=otdit.next();
4439       TaskIndex ti=new TaskIndex(otd.td, otd.getIndex());
4440       r.put(ti, otd);
4441     }
4442
4443     LinkedList<OptionalTaskDescriptor> l=new LinkedList<OptionalTaskDescriptor>();
4444     for(Iterator it=r.keySet().iterator(); it.hasNext();) {
4445       Set s=r.get(it.next());
4446       for(Iterator it2=s.iterator(); it2.hasNext();) {
4447         OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next();
4448         l.add(otd);
4449       }
4450     }
4451
4452     return l;
4453   }
4454
4455   protected void outputTransCode(PrintWriter output) {
4456   }
4457
4458
4459
4460   // override these methods in a subclass of BuildCode
4461   // to generate code for additional systems
4462   protected void additionalIncludesMethodsHeader( PrintWriter outmethodheader ) {}
4463   protected void preCodeGenInitialization() {}
4464   protected void postCodeGenCleanUp() {}
4465   protected void additionalCodeGen( PrintWriter outmethodheader,
4466                                     PrintWriter outstructs,
4467                                     PrintWriter outmethod ) {}
4468   protected void additionalCodeAtTopOfMain( PrintWriter outmethod ) {}
4469   protected void additionalCodeAtBottomOfMain( PrintWriter outmethod ) {}
4470   protected void additionalIncludesMethodsImplementation( PrintWriter outmethod ) {}
4471   protected void additionalIncludesStructsHeader( PrintWriter outstructs ) {}
4472   protected void additionalClassObjectFields( PrintWriter outclassdefs ) {}
4473   protected void additionalCodeAtTopMethodsImplementation( PrintWriter outmethod ) {}
4474   protected void additionalCodeAtTopFlatMethodBody( PrintWriter output, FlatMethod fm ) {}
4475   protected void additionalCodePreNode( FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output ) {}
4476   protected void additionalCodePostNode( FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output ) {}
4477 }
4478
4479
4480
4481
4482
4483