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