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