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