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