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