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