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