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