05010567130012bf89c7b2448fd4a7d1da13835b
[IRC.git] / Robust / src / IR / Flat / BuildCodeMultiCore.java
1 package IR.Flat;
2
3 import java.io.FileOutputStream;
4 import java.io.PrintWriter;
5 import java.util.HashSet;
6 import java.util.Hashtable;
7 import java.util.Iterator;
8 import java.util.LinkedList;
9 import java.util.Queue;
10 import java.util.Set;
11 import java.util.Vector;
12
13 import Analysis.Scheduling.Schedule;
14 import Analysis.TaskStateAnalysis.FEdge;
15 import Analysis.TaskStateAnalysis.FlagState;
16 import Analysis.TaskStateAnalysis.SafetyAnalysis;
17 import Analysis.OwnershipAnalysis.AllocationSite;
18 import Analysis.OwnershipAnalysis.OwnershipAnalysis;
19 import Analysis.OwnershipAnalysis.HeapRegionNode;
20 import Analysis.Prefetch.*;
21 import IR.ClassDescriptor;
22 import IR.Descriptor;
23 import IR.FlagDescriptor;
24 import IR.MethodDescriptor;
25 import IR.State;
26 import IR.TagVarDescriptor;
27 import IR.TaskDescriptor;
28 import IR.TypeDescriptor;
29 import IR.TypeUtil;
30 import IR.VarDescriptor;
31 import IR.Tree.DNFFlag;
32 import IR.Tree.DNFFlagAtom;
33 import IR.Tree.FlagExpressionNode;
34 import IR.Tree.TagExpressionList;
35
36 public class BuildCodeMultiCore extends BuildCode {
37   private Vector<Schedule> scheduling;
38   int coreNum;
39   int tcoreNum;
40   int gcoreNum;
41   Schedule currentSchedule;
42   Hashtable[] fsate2qnames;
43   String objqarrayprefix= "objqueuearray4class";
44   String objqueueprefix = "objqueue4parameter_";
45   String paramqarrayprefix = "paramqueuearray4task";
46   String coreqarrayprefix = "paramqueuearrays_core";
47   String taskprefix = "task_";
48   String taskarrayprefix = "taskarray_core";
49   String otqueueprefix = "___otqueue";
50   int startupcorenum;    // record the core containing startup task, suppose only one core can hava startup object
51
52   protected OwnershipAnalysis m_oa;
53   protected Vector<Vector<Integer>> m_aliasSets;
54   Hashtable<Integer, Vector<FlatNew>> m_aliasFNTbl4Para;
55   Hashtable<FlatNew, Vector<FlatNew>> m_aliasFNTbl;
56   Hashtable<FlatNew, Vector<Integer>> m_aliaslocksTbl4FN;
57
58   public BuildCodeMultiCore(State st, 
59                             Hashtable temptovar, 
60                             TypeUtil typeutil, 
61                             SafetyAnalysis sa, 
62                             Vector<Schedule> scheduling, 
63                             int coreNum, 
64                             int gcoreNum) {
65     super(st, temptovar, typeutil, sa);
66     this.scheduling = scheduling;
67     this.coreNum = coreNum; // # of the active cores
68     this.tcoreNum = coreNum;  // # of the cores setup by users
69     this.gcoreNum = gcoreNum; // # of the cores for gc if any
70     this.currentSchedule = null;
71     this.fsate2qnames = null;
72     this.startupcorenum = 0;
73
74     // sometimes there are extra cores then needed in scheduling
75     // TODO
76     // currently, it is guaranteed that in scheduling, the corenum
77     // is started from 0 and continuous.
78     // MAY need modification here in the future when take hardware
79     // information into account.
80     if(this.scheduling.size() < this.coreNum) {
81       this.coreNum = this.scheduling.size();
82     }
83
84     this.m_oa = null;
85     this.m_aliasSets = null;
86     this.m_aliasFNTbl4Para = null;
87     this.m_aliasFNTbl = null;
88     this.m_aliaslocksTbl4FN = null;
89   }
90
91   public void setOwnershipAnalysis(OwnershipAnalysis m_oa) {
92     this.m_oa = m_oa;
93   }
94
95   public void buildCode() {
96     /* Create output streams to write to */
97     PrintWriter outclassdefs=null;
98     PrintWriter outglobaldefs=null;
99     PrintWriter outglobaldefsprim=null;
100     PrintWriter outstructs=null;
101     PrintWriter outmethodheader=null;
102     PrintWriter outmethod=null;
103     PrintWriter outvirtual=null;
104     PrintWriter outtask=null;
105     PrintWriter outtaskdefs=null;
106     //PrintWriter outoptionalarrays=null;
107     //PrintWriter optionalheaders=null;
108
109     try {
110       outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
111       outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
112       outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
113       outglobaldefs=new PrintWriter(new FileOutputStream(PREFIX+"globaldefs.h"), true);
114       outglobaldefsprim=new PrintWriter(new FileOutputStream(PREFIX+"globaldefsprim.h"), true);
115       outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
116       outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
117       if (state.TASK) {
118         outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
119         outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
120         /* optional
121            if (state.OPTIONAL){
122             outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
123             optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
124            } */
125       }
126       /*if (state.structfile!=null) {
127           outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
128          }*/
129     } catch (Exception e) {
130       e.printStackTrace();
131       System.exit(-1);
132     }
133     
134     /* Fix field safe symbols due to shadowing */
135     FieldShadow.handleFieldShadow(state);
136
137     /* Build the virtual dispatch tables */
138
139     buildVirtualTables(outvirtual);
140     
141     /* Tag the methods that are invoked by static blocks */
142     tagMethodInvokedByStaticBlock();
143
144     /* Output includes */
145     outmethodheader.println("#ifndef METHODHEADERS_H");
146     outmethodheader.println("#define METHODHEADERS_H");
147     outmethodheader.println("#include \"structdefs.h\"");
148     /*if (state.DSM)
149         outmethodheader.println("#include \"dstm.h\"");*/
150
151     /* Output Structures */
152     outputStructs(outstructs);
153     
154     outglobaldefs.println("#ifndef __GLOBALDEF_H_");
155     outglobaldefs.println("#define __GLOBALDEF_H_");
156     outglobaldefs.println("");
157     outglobaldefs.println("struct global_defs_t {");
158     outglobaldefs.println("  int size;");
159     outglobaldefs.println("  void * next;");
160
161     outglobaldefsprim.println("#ifndef __GLOBALDEFPRIM_H_");
162     outglobaldefsprim.println("#define __GLOBALDEFPRIM_H_");
163     outglobaldefsprim.println("");
164     outglobaldefsprim.println("struct global_defsprim_t {");
165
166     // Output the C class declarations
167     // These could mutually reference each other
168     outclassdefs.println("#ifndef __CLASSDEF_H_");
169     outclassdefs.println("#define __CLASSDEF_H_");
170     outputClassDeclarations(outclassdefs, outglobaldefs, outglobaldefsprim);
171
172     // Output function prototypes and structures for parameters
173     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
174     int numclasses = this.state.numClasses();
175     while(it.hasNext()) {
176       ClassDescriptor cn=(ClassDescriptor)it.next();
177       generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs, outglobaldefsprim);
178     }
179     outclassdefs.println("#include \"globaldefs.h\"");
180     outclassdefs.println("#include \"globaldefsprim.h\"");
181     outclassdefs.println("#endif");
182     outclassdefs.close();
183     outglobaldefs.println("};");
184     outglobaldefs.println("");
185     outglobaldefs.println("extern struct global_defs_t * global_defs_p;");
186     outglobaldefs.println("#endif");
187     outglobaldefs.flush();
188     outglobaldefs.close();
189
190     outglobaldefsprim.println("};");
191     outglobaldefsprim.println("");
192     outglobaldefsprim.println("extern struct global_defsprim_t * global_defsprim_p;");
193     outglobaldefsprim.println("#endif");
194     outglobaldefsprim.flush();
195     outglobaldefsprim.close();
196
197     if (state.TASK) {
198       /* Map flags to integers */
199       /* The runtime keeps track of flags using these integers */
200       it=state.getClassSymbolTable().getDescriptorsIterator();
201       while(it.hasNext()) {
202         ClassDescriptor cn=(ClassDescriptor)it.next();
203         mapFlags(cn);
204       }
205       /* Generate Tasks */
206       generateTaskStructs(outstructs, outmethodheader);
207
208       /* Outputs generic task structures if this is a task
209          program */
210       outputTaskTypes(outtask);
211     }
212
213     /* Build the actual methods */
214     outputMethods(outmethod);
215
216     if (state.TASK) {
217       Iterator[] taskits = new Iterator[this.coreNum];
218       for(int i = 0; i < taskits.length; ++i) {
219         taskits[i] = null;
220       }
221       int[] numtasks = new int[this.coreNum];
222       int[][] numqueues = new int[this.coreNum][numclasses];
223       /* Output code for tasks */
224       for(int i = 0; i < this.scheduling.size(); ++i) {
225         this.currentSchedule = this.scheduling.elementAt(i);
226         outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
227       }
228
229       // Output task descriptors
230       boolean comma = false;
231       outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
232       boolean needcomma = false;
233       for(int i = 0; i < numqueues.length ; ++i) {
234         if(needcomma) {
235           outtaskdefs.println(",");
236         } else {
237           needcomma = true;
238         }
239         outtaskdefs.println("/* object queue array for core " + i + "*/");
240         outtaskdefs.print("{");
241         comma = false;
242         for(int j = 0; j < numclasses; ++j) {
243           if(comma) {
244             outtaskdefs.println(",");
245           } else {
246             comma = true;
247           }
248           outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
249         }
250         outtaskdefs.print("}");
251       }
252       outtaskdefs.println("};");
253       needcomma = false;
254       outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
255       for(int i = 0; i < numqueues.length; ++i) {
256         if(needcomma) {
257           outtaskdefs.println(",");
258         } else {
259           needcomma = true;
260         }
261         int[] tmparray = numqueues[i];
262         comma = false;
263         outtaskdefs.print("{");
264         for(int j = 0; j < tmparray.length; ++j) {
265           if(comma) {
266             outtaskdefs.print(",");
267           } else {
268             comma = true;
269           }
270           outtaskdefs.print(tmparray[j]);
271         }
272         outtaskdefs.print("}");
273       }
274       outtaskdefs.println("};");
275
276       /* parameter queue arrays for all the tasks*/
277       outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
278       needcomma = false;
279       for(int i = 0; i < this.coreNum ; ++i) {
280         if(needcomma) {
281           outtaskdefs.println(",");
282         } else {
283           needcomma = true;
284         }
285         outtaskdefs.println("/* parameter queue array for core " + i + "*/");
286         outtaskdefs.print(this.coreqarrayprefix + i);
287       }
288       outtaskdefs.println("};");
289
290       for(int i = 0; i < taskits.length; ++i) {
291         outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
292         Iterator taskit = taskits[i];
293         if(taskit != null) {
294           boolean first=true;
295           while(taskit.hasNext()) {
296             TaskDescriptor td=(TaskDescriptor)taskit.next();
297             if (first)
298               first=false;
299             else
300               outtaskdefs.println(",");
301             outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
302           }
303         }
304         outtaskdefs.println();
305         outtaskdefs.println("};");
306       }
307       outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
308       comma = false;
309       for(int i = 0; i < taskits.length; ++i) {
310         if (comma)
311           outtaskdefs.println(",");
312         else
313           comma = true;
314         outtaskdefs.print(this.taskarrayprefix + i);
315       }
316       outtaskdefs.println("};");
317
318       outtaskdefs.print("int numtasks[]= {");
319       comma = false;
320       for(int i = 0; i < taskits.length; ++i) {
321         if (comma)
322           outtaskdefs.print(",");
323         else
324           comma=true;
325         outtaskdefs.print(numtasks[i]);
326       }
327       outtaskdefs.println("};");
328       outtaskdefs.println("int corenum=0;");
329
330       outtaskdefs.close();
331       outtask.println("#endif");
332       outtask.close();
333       /* Record maximum number of task parameters */
334       outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
335       /* Record maximum number of all types, i.e. length of classsize[] */
336       outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays() + state.numInterfaces()));
337       /* Record number of total cores */
338       outstructs.println("#define NUMCORES "+this.tcoreNum);
339       /* Record number of active cores */
340       outstructs.println("#define NUMCORESACTIVE "+this.coreNum); // this.coreNum 
341                                       // can be reset by the scheduling analysis
342       /* Record number of garbage collection cores */
343       outstructs.println("#ifdef MULTICORE_GC");
344       outstructs.println("#define NUMCORES4GC "+this.gcoreNum);
345       outstructs.println("#endif");
346       /* Record number of core containing startup task */
347       outstructs.println("#define STARTUPCORE "+this.startupcorenum);
348     }     //else if (state.main!=null) {
349           /* Generate main method */
350           // outputMainMethod(outmethod);
351           //}
352
353     /* Generate information for task with optional parameters */
354     /*if (state.TASK&&state.OPTIONAL){
355         generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
356         outoptionalarrays.close();
357        } */
358
359     /* Output structure definitions for repair tool */
360     /*if (state.structfile!=null) {
361         buildRepairStructs(outrepairstructs);
362         outrepairstructs.close();
363        }*/
364
365     /* Close files */
366     outmethodheader.println("#endif");
367     outmethodheader.close();
368     outmethod.close();
369     outstructs.println("#endif");
370     outstructs.close();
371   }
372
373   /** This function outputs (1) structures that parameters are
374    * passed in (when PRECISE GC is enabled) and (2) function
375    * prototypes for the tasks */
376
377   protected void generateTaskStructs(PrintWriter output, 
378                                    PrintWriter headersout) {
379     /* Cycle through tasks */
380     for(int i = 0; i < this.scheduling.size(); ++i) {
381       Schedule tmpschedule = this.scheduling.elementAt(i);
382       int num = tmpschedule.getCoreNum();
383       Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
384
385       while(taskit.hasNext()) {
386         /* Classify parameters */
387         TaskDescriptor task=taskit.next();
388         FlatMethod fm=state.getMethodFlat(task);
389         generateTempStructs(fm);
390
391         ParamsObject objectparams=(ParamsObject) paramstable.get(task);
392         TempObject objecttemps=(TempObject) tempstable.get(task);
393
394         /* Output parameter structure */
395         if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
396           output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
397           output.println("  int size;");
398           output.println("  void * next;");
399           for(int j=0; j<objectparams.numPointers(); j++) {
400             TempDescriptor temp=objectparams.getPointer(j);
401             output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
402           }
403
404           output.println("};\n");
405           if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
406             maxtaskparams=objectparams.numPointers()+fm.numTags();
407           }
408         }
409
410         /* Output temp structure */
411         if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
412           output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
413           output.println("  int size;");
414           output.println("  void * next;");
415           for(int j=0; j<objecttemps.numPointers(); j++) {
416             TempDescriptor temp=objecttemps.getPointer(j);
417             if (temp.getType().isNull())
418               output.println("  void * "+temp.getSafeSymbol()+";");
419             else if(temp.getType().isTag())
420               output.println("  struct "+
421                              (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
422             else
423               output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
424           }
425           output.println("};\n");
426         }
427
428         /* Output task declaration */
429         headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
430
431         if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
432           headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
433         } else
434           headersout.print("void * parameterarray[]");
435         headersout.println(");\n");
436       }
437     }
438
439   }
440
441   /* This method outputs code for each task. */
442
443   protected void outputTaskCode(PrintWriter outtaskdefs, 
444                                   PrintWriter outmethod, 
445                                   PrintWriter outtask, 
446                                   Iterator[] taskits, 
447                                   int[] numtasks,
448                               int[][] numqueues) {
449     /* Compile task based program */
450     outtaskdefs.println("#include \"task.h\"");
451     outtaskdefs.println("#include \"methodheaders.h\"");
452
453     /* Output object transfer queues into method.c*/
454     generateObjectTransQueues(outmethod);
455
456     //Vector[] qnames = new Vector[2];
457     int numclasses = numqueues[0].length;
458     Vector qnames[]= new Vector[numclasses];
459     for(int i = 0; i < qnames.length; ++i) {
460       qnames[i] = null;
461     }
462     Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
463     while(taskit.hasNext()) {
464       TaskDescriptor td=taskit.next();
465       FlatMethod fm=state.getMethodFlat(td);
466       generateTaskMethod(fm, outmethod);
467       generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
468     }
469
470     // generate queuearray for this core
471     int num = this.currentSchedule.getCoreNum();
472     boolean comma = false;
473     for(int i = 0; i < qnames.length; ++i) {
474       outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
475       outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
476       comma = false;
477       Vector tmpvector = qnames[i];
478       if(tmpvector != null) {
479         for(int j = 0; j < tmpvector.size(); ++j) {
480           if(comma) {
481             outtaskdefs.println(",");
482           } else {
483             comma = true;
484           }
485           outtaskdefs.print("&" + tmpvector.elementAt(j));
486         }
487         numqueues[num][i] = tmpvector.size();
488       } else {
489         numqueues[num][i] = 0;
490       }
491       outtaskdefs.println("};");
492     }
493
494     /* All the queues for tasks residing on this core*/
495     comma = false;
496     outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
497     outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
498     taskit=this.currentSchedule.getTasks().iterator();
499     while(taskit.hasNext()) {
500       if (comma) {
501         outtaskdefs.println(",");
502       } else {
503         comma = true;
504       }
505       TaskDescriptor td=taskit.next();
506       outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
507     }
508     outtaskdefs.println("};");
509
510     // record the iterator of tasks on this core
511     taskit=this.currentSchedule.getTasks().iterator();
512     taskits[num] = taskit;
513     numtasks[num] = this.currentSchedule.getTasks().size();
514   }
515
516   /** Prints out definitions for generic task structures */
517   protected void outputTaskTypes(PrintWriter outtask) {
518     outtask.println("#ifndef _TASK_H");
519     outtask.println("#define _TASK_H");
520     outtask.println("#include \"ObjectHash.h\"");
521     outtask.println("#include \"structdefs.h\"");
522     outtask.println("#include \"Queue.h\"");
523     outtask.println("#include <string.h>");
524         outtask.println("#include \"runtime_arch.h\"");
525     //outtask.println("#ifdef RAW");
526     //outtask.println("#include <raw.h>");
527     //outtask.println("#endif");
528     outtask.println();
529     outtask.println("struct tagobjectiterator {");
530     outtask.println("  int istag; /* 0 if object iterator, 1 if tag iterator */");
531     outtask.println("  struct ObjectIterator it; /* Object iterator */");
532     outtask.println("  struct ObjectHash * objectset;");
533     outtask.println("#ifdef OPTIONAL");
534     outtask.println("  int failedstate;");
535     outtask.println("#endif");
536     outtask.println("  int slot;");
537     outtask.println("  int tagobjindex; /* Index for tag or object depending on use */");
538     outtask.println("  /*if tag we have an object binding */");
539     outtask.println("  int tagid;");
540     outtask.println("  int tagobjectslot;");
541     outtask.println("  /*if object, we may have one or more tag bindings */");
542     outtask.println("  int numtags;");
543     outtask.println("  int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
544     outtask.println("};");
545     outtask.println();
546     outtask.println("struct parameterwrapper {");
547     outtask.println("  //int type;");
548     outtask.println("  struct ObjectHash * objectset;");
549     outtask.println("  int numberofterms;");
550     outtask.println("  int * intarray;");
551     outtask.println("  int numbertags;");
552     outtask.println("  int * tagarray;");
553     outtask.println("  struct taskdescriptor * task;");
554     outtask.println("  int slot;");
555     outtask.println("  struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
556     outtask.println("};");
557     outtask.println();
558     outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
559     outtask.println("extern int numqueues[][NUMCLASSES];");
560     outtask.println();
561     outtask.println("struct parameterdescriptor {");
562     outtask.println("  int type;");
563     outtask.println("  int numberterms;");
564     outtask.println("  int *intarray;");
565     outtask.println("  struct parameterwrapper * queue;");
566     outtask.println("  int numbertags;");
567     outtask.println("  int *tagarray;");
568     outtask.println("};");
569     outtask.println();
570     outtask.println("struct taskdescriptor {");
571     outtask.println("  void * taskptr;");
572     outtask.println("  int numParameters;");
573     outtask.println("  int numTotal;");
574     outtask.println("  struct parameterdescriptor **descriptorarray;");
575     outtask.println("  char * name;");
576     outtask.println("};");
577     outtask.println();
578     outtask.println("extern struct taskdescriptor ** taskarray[];");
579     outtask.println("extern int numtasks[];");
580     outtask.println("extern int corenum;");     // define corenum to identify different core
581     outtask.println("extern struct parameterwrapper *** paramqueues[];");
582     outtask.println();
583   }
584
585   protected void generateObjectTransQueues(PrintWriter output) {
586     if(this.fsate2qnames == null) {
587       this.fsate2qnames = new Hashtable[this.coreNum];
588       for(int i = 0; i < this.fsate2qnames.length; ++i) {
589         this.fsate2qnames[i] = null;
590       }
591     }
592     int num = this.currentSchedule.getCoreNum();
593     assert(this.fsate2qnames[num] == null);
594     Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
595     this.fsate2qnames[num] = flag2qname;
596     Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
597     if(targetCoreTbl != null) {
598       Object[] keys = targetCoreTbl.keySet().toArray();
599       output.println();
600       output.println("/* Object transfer queues for core" + num + ".*/");
601       for(int i = 0; i < keys.length; ++i) {
602         FlagState tmpfstate = (FlagState)keys[i];
603         Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
604         String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
605         String queueins = queuename + "ins";
606         flag2qname.put(tmpfstate, queuename);
607         output.println("struct " + queuename + " {");
608         output.println("  int * cores;");
609         output.println("  int index;");
610         output.println("  int length;");
611         output.println("};");
612         output.print("int " + queuename + "cores[] = {");
613         for(int j = 0; j < targetcores.length; ++j) {
614           if(j > 0) {
615             output.print(", ");
616           }
617           output.print(((Integer)targetcores[j]).intValue());
618         }
619         output.println("};");
620         output.println("struct " + queuename + " " + queueins + "= {");
621         output.println(/*".cores = " + */ queuename + "cores,");
622         output.println(/*".index = " + */ "0,");
623         output.println(/*".length = " +*/ targetcores.length + "};");
624       }
625     }
626     output.println();
627   }
628
629   protected void generateTaskMethod(FlatMethod fm, 
630                                   PrintWriter output) {
631     /*if (State.PRINTFLAT)
632         System.out.println(fm.printMethod());*/
633     TaskDescriptor task=fm.getTask();
634     assert(task != null);
635     int num = this.currentSchedule.getCoreNum();
636
637     //ParamsObject objectparams=(ParamsObject)paramstable.get(task);
638     generateTaskHeader(fm, task,output);
639
640     TempObject objecttemp=(TempObject) tempstable.get(task);
641
642     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
643       output.print("   struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
644
645       output.print(objecttemp.numPointers()+",");
646       output.print(paramsprefix);
647       for(int j=0; j<objecttemp.numPointers(); j++)
648         output.print(", NULL");
649       output.println("};");
650     }
651
652     for(int i=0; i<objecttemp.numPrimitives(); i++) {
653       TempDescriptor td=objecttemp.getPrimitive(i);
654       TypeDescriptor type=td.getType();
655       if (type.isNull())
656         output.println("   void * "+td.getSafeSymbol()+";");
657       else if (state.MGC && type.isClass() && type.getClassDesc().isEnum()) {
658         output.println("   int " + td.getSafeSymbol()+";");
659       } else if (type.isClass()||type.isArray())
660         output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
661       else
662         output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
663     }
664
665     for(int i = 0; i < fm.numParameters(); ++i) {
666       TempDescriptor temp = fm.getParameter(i);
667       output.println("   int "+generateTempFlagName(fm, temp)+" = "+generateTemp(fm, temp)+
668                      "->flag;");
669     }
670
671     /* Assign labels to FlatNode's if necessary.*/
672
673     Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm, null);
674
675     /* Check to see if we need to do a GC if this is a
676      * multi-threaded program...*/
677     if(this.state.MULTICOREGC) {
678       output.println("if(gcflag) gc("+localsprefixaddr+");");
679     }
680
681     /* Create queues to store objects need to be transferred to other cores and their destination*/
682     //output.println("   struct Queue * totransobjqueue = createQueue();");
683     output.println("   clearQueue(totransobjqueue);");
684     output.println("   struct transObjInfo * tmpObjInfo = NULL;");
685
686     this.m_aliasSets = null;
687     this.m_aliasFNTbl4Para = null;
688     this.m_aliasFNTbl = null;
689     this.m_aliaslocksTbl4FN = null;
690     outputAliasLockCode(fm, output);
691
692     /* generate print information for RAW version */
693     output.println("#ifdef MULTICORE");
694         if(this.state.RAW) {
695                 output.println("{");
696                 output.println("int tmpsum = 0;");
697                 output.println("char * taskname = \"" + task.getSymbol() + "\";");
698                 output.println("int tmplen = " + task.getSymbol().length() + ";");
699                 output.println("int tmpindex = 1;");
700                 output.println("for(;tmpindex < tmplen; tmpindex++) {");
701                 output.println("   tmpsum = tmpsum * 10 + *(taskname + tmpindex) - '0';");
702                 output.println("}");
703         }
704     output.println("#ifdef RAWPATH");
705         if(this.state.RAW) {
706                 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
707                 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);"); 
708         } else {
709                 //output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
710                 output.println("printf(\"(%x,%x) Process %x(%d): task %s\\n\", udn_tile_coord_x(), udn_tile_coord_y(), corenum, corenum, \"" + task.getSymbol() + "\");");
711                 //output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
712         }
713         //output.println("BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());");
714     output.println("#endif");
715     output.println("#ifdef DEBUG");
716         if(this.state.RAW) {
717                 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
718                 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
719         } else {
720                 //output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
721                 output.println("printf(\"(%x,%x) Process %x(%d): task %s\\n\", udn_tile_coord_x(), udn_tile_coord_y(), corenum, corenum, \"" + task.getSymbol() + "\");");
722                 //output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
723         }
724     output.println("#endif");
725         if(this.state.RAW) {
726                 output.println("}");
727         }
728         output.println("#endif");
729
730     for(int i = 0; i < fm.numParameters(); ++i) {
731       TempDescriptor temp = fm.getParameter(i);
732       output.println("   ++" + generateTemp(fm, temp)+"->version;");
733     }
734
735     /* Do the actual code generation */
736     FlatNode current_node=null;
737     HashSet tovisit=new HashSet();
738     HashSet visited=new HashSet();
739     tovisit.add(fm.getNext(0));
740     while(current_node!=null||!tovisit.isEmpty()) {
741       if (current_node==null) {
742         current_node=(FlatNode)tovisit.iterator().next();
743         tovisit.remove(current_node);
744       }
745       visited.add(current_node);
746       if (nodetolabel.containsKey(current_node))
747         output.println("L"+nodetolabel.get(current_node)+":");
748       /*if (state.INSTRUCTIONFAILURE) {
749           if (state.THREAD||state.DSM) {
750               output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
751           }
752           else
753               output.println("if ((--instructioncount)==0) injectinstructionfailure();");
754          }*/
755       if (current_node.numNext()==0) {
756         output.print("   ");
757         generateFlatNode(fm, current_node, output);
758         if (current_node.kind()!=FKind.FlatReturnNode) {
759           //output.println("   flushAll();");
760           output.println("#ifdef CACHEFLUSH");
761           output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
762           output.println("#ifdef DEBUG");
763           output.println("BAMBOO_DEBUGPRINT(0xec00);");
764           output.println("#endif");
765           output.println("BAMBOO_CACHE_FLUSH_ALL();");
766           output.println("#ifdef DEBUG");
767           output.println("BAMBOO_DEBUGPRINT(0xecff);");
768           output.println("#endif");
769           output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
770           output.println("#endif");
771           outputTransCode(output);
772           output.println("   return;");
773         }
774         current_node=null;
775       } else if(current_node.numNext()==1) {
776         output.print("   ");
777         generateFlatNode(fm, current_node, output);
778         FlatNode nextnode=current_node.getNext(0);
779         if (visited.contains(nextnode)) {
780           output.println("goto L"+nodetolabel.get(nextnode)+";");
781           current_node=null;
782         } else
783           current_node=nextnode;
784       } else if (current_node.numNext()==2) {
785         /* Branch */
786         output.print("   ");
787         generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
788         if (!visited.contains(current_node.getNext(1)))
789           tovisit.add(current_node.getNext(1));
790         if (visited.contains(current_node.getNext(0))) {
791           output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
792           current_node=null;
793         } else
794           current_node=current_node.getNext(0);
795       } else throw new Error();
796     }
797
798     output.println("}\n\n");
799   }
800
801   /** This method outputs TaskDescriptor information */
802   protected void generateTaskDescriptor(PrintWriter output, 
803                                       PrintWriter outtask, 
804                                       FlatMethod fm, 
805                                       TaskDescriptor task, 
806                                       Vector[] qnames) {
807     int num = this.currentSchedule.getCoreNum();
808
809     output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
810
811     for (int i=0; i<task.numParameters(); i++) {
812       VarDescriptor param_var=task.getParameter(i);
813       TypeDescriptor param_type=task.getParamType(i);
814       FlagExpressionNode param_flag=task.getFlag(param_var);
815       TagExpressionList param_tag=task.getTag(param_var);
816
817       int dnfterms;
818       if (param_flag==null) {
819         output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
820         output.println("0x0, 0x0 };");
821         dnfterms=1;
822       } else {
823         DNFFlag dflag=param_flag.getDNF();
824         dnfterms=dflag.size();
825
826         Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
827         output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
828         for(int j=0; j<dflag.size(); j++) {
829           if (j!=0)
830             output.println(",");
831           Vector term=dflag.get(j);
832           int andmask=0;
833           int checkmask=0;
834           for(int k=0; k<term.size(); k++) {
835             DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
836             FlagDescriptor fd=dfa.getFlag();
837             boolean negated=dfa.getNegated();
838             int flagid=1<<((Integer)flags.get(fd)).intValue();
839             andmask|=flagid;
840             if (!negated)
841               checkmask|=flagid;
842           }
843           output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
844         }
845         output.println("};");
846       }
847
848       output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
849       //BUG...added next line to fix, test with any task program
850       if (param_tag!=null)
851         for(int j=0; j<param_tag.numTags(); j++) {
852           if (j!=0)
853             output.println(",");
854           /* for each tag we need */
855           /* which slot it is */
856           /* what type it is */
857           TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
858           TempDescriptor tmp=param_tag.getTemp(j);
859           int slot=fm.getTagInt(tmp);
860           output.println(slot+", "+state.getTagId(tvd.getTag()));
861         }
862       output.println("};");
863
864       // generate object queue for this parameter
865       String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
866       if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
867         this.startupcorenum = num;
868       }
869       if(qnames[param_type.getClassDesc().getId()] == null) {
870         qnames[param_type.getClassDesc().getId()] = new Vector();
871       }
872       qnames[param_type.getClassDesc().getId()].addElement(qname);
873       outtask.println("extern struct parameterwrapper " + qname + ";");
874       output.println("struct parameterwrapper " + qname + "={");
875       output.println(".objectset = 0,");      // objectset
876       output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+",");     // numberofterms
877       output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+",");    // intarray
878       // numbertags
879       if (param_tag!=null)
880         output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
881       else
882         output.println("/* number of tags */ .numbertags = 0,");
883       output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+",");    // tagarray
884       output.println(".task = 0,");      // task
885       output.println(".slot = " + i + ",");    // slot
886       // iterators
887       output.println("};");
888
889       output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
890       output.println("/* type */"+param_type.getClassDesc().getId()+",");
891       output.println("/* number of DNF terms */"+dnfterms+",");
892       output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+",");    // intarray
893       output.println("&" + qname + ",");     // queue
894       //BUG, added next line to fix and else statement...test
895       //with any task program
896       if (param_tag!=null)
897         output.println("/* number of tags */"+param_tag.numTags()+",");
898       else
899         output.println("/* number of tags */ 0,");
900       output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num));     // tagarray
901       output.println("};");
902     }
903
904     /* parameter queues for this task*/
905     output.println("struct parameterwrapper * " + this.paramqarrayprefix + task.getCoreSafeSymbol(num)+"[] = {");
906     for (int i=0; i<task.numParameters(); i++) {
907       if (i!=0)
908         output.println(",");
909       output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
910     }
911     output.println("};");
912
913     output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
914     for (int i=0; i<task.numParameters(); i++) {
915       if (i!=0)
916         output.println(",");
917       output.print("&parameter_"+i+"_"+task.getCoreSafeSymbol(num));
918     }
919     output.println("};");
920
921     output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
922     output.println("&"+task.getCoreSafeSymbol(num)+",");
923     output.println("/* number of parameters */" +task.numParameters() + ",");
924     int numtotal=task.numParameters()+fm.numTags();
925     output.println("/* number total parameters */" +numtotal + ",");
926     output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
927     output.println("\""+task.getSymbol()+"\"");
928     output.println("};");
929
930     output.println();
931   }
932
933   /** This method generates header information for the task
934    *  referenced by the Descriptor des. */
935
936   protected void generateTaskHeader(FlatMethod fm, 
937                                   Descriptor des, 
938                                   PrintWriter output) {
939     /* Print header */
940     ParamsObject objectparams=(ParamsObject)paramstable.get(des);
941     TaskDescriptor task=(TaskDescriptor) des;
942
943     int num = this.currentSchedule.getCoreNum();
944     //catch the constructor case
945     output.print("void ");
946     output.print(task.getCoreSafeSymbol(num)+"(");
947
948     boolean printcomma=false;
949     if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
950       output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
951       printcomma=true;
952     }
953
954     if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
955       /* Imprecise Task */
956       output.println("void * parameterarray[]) {");
957       /* Unpack variables */
958       for(int i=0; i<objectparams.numPrimitives(); i++) {
959         TempDescriptor temp=objectparams.getPrimitive(i);
960         output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
961       }
962       for(int i=0; i<fm.numTags(); i++) {
963         TempDescriptor temp=fm.getTag(i);
964         int offset=i+objectparams.numPrimitives();
965         output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];");     // add i to fix bugs of duplicate definition of tags
966       }
967
968       if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
969         maxtaskparams=objectparams.numPrimitives()+fm.numTags();
970     } else output.println(") {");
971   }
972
973   protected void generateFlagOrAnd(FlatFlagActionNode ffan, 
974                                    FlatMethod fm, 
975                                    TempDescriptor temp,
976                                    PrintWriter output, 
977                                    int ormask, 
978                                    int andmask) {
979     if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
980       output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
981     } else {
982       int num = this.currentSchedule.getCoreNum();
983       ClassDescriptor cd = temp.getType().getClassDesc();
984       Vector<FlagState> initfstates = ffan.getInitFStates(cd);
985       for(int i = 0; i < initfstates.size(); ++i) {
986         FlagState tmpFState = initfstates.elementAt(i);
987         output.println("{");
988         QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
989         output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+
990                        ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
991                        ", " + qinfo.length + ");");
992         output.println("}");
993       }
994       if(ffan.getTaskType()==FlatFlagActionNode.TASKEXIT) {
995           // generate codes for profiling, recording which task exit it is
996           output.println("#ifdef PROFILE");
997           output.println("setTaskExitIndex(" + ffan.getTaskExitIndex() + ");");
998           output.println("#endif");
999       }
1000     }
1001   }
1002
1003   protected void generateObjectDistribute(FlatFlagActionNode ffan, 
1004                                               FlatMethod fm, 
1005                                               TempDescriptor temp,
1006                                           PrintWriter output) {
1007     ClassDescriptor cd = temp.getType().getClassDesc();
1008     Vector<FlagState> initfstates = null;
1009     Vector[] targetFStates = null;
1010     if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
1011       targetFStates = new Vector[1];
1012       targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
1013     } else {
1014       initfstates = ffan.getInitFStates(cd);
1015       targetFStates = new Vector[initfstates.size()];
1016       for(int i = 0; i < initfstates.size(); ++i) {
1017         FlagState fs = initfstates.elementAt(i);
1018         targetFStates[i] = ffan.getTargetFStates(fs);
1019
1020         if(!fs.isSetmask()) {
1021           Hashtable flags=(Hashtable)flagorder.get(cd);
1022           int andmask=0;
1023           int checkmask=0;
1024           Iterator it_flags = fs.getFlags();
1025           while(it_flags.hasNext()) {
1026             FlagDescriptor fd = (FlagDescriptor)it_flags.next();
1027             int flagid=1<<((Integer)flags.get(fd)).intValue();
1028             andmask|=flagid;
1029             checkmask|=flagid;
1030           }
1031           fs.setAndmask(andmask);
1032           fs.setCheckmask(checkmask);
1033           fs.setSetmask(true);
1034         }
1035       }
1036     }
1037     boolean isolate = true;     // check if this flagstate can associate to some task with multiple params which can
1038                                 // reside on multiple cores
1039     if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
1040       // ServerSocket object will always reside on current core
1041       for(int j = 0; j < targetFStates.length; ++j) {
1042         if(initfstates != null) {
1043           FlagState fs = initfstates.elementAt(j);
1044           output.println("if(" + generateTempFlagName(fm, temp) + "&(0x" + Integer.toHexString(fs.getAndmask())
1045                          + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1046         }
1047         Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1048         for(int i = 0; i < tmpfstates.size(); ++i) {
1049           FlagState tmpFState = tmpfstates.elementAt(i);
1050           // TODO
1051           // may have bugs here
1052           output.println("/* reside on this core*");
1053           output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1054         }
1055         if(initfstates != null) {
1056           output.println("}");
1057         }
1058       }
1059       return;
1060     }
1061
1062     int num = this.currentSchedule.getCoreNum();
1063     Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
1064     for(int j = 0; j < targetFStates.length; ++j) {
1065       FlagState fs = null;
1066       if(initfstates != null) {
1067         fs = initfstates.elementAt(j);
1068         output.println("if((" + generateTempFlagName(fm, temp) + "&(0x" + Integer.toHexString(fs.getAndmask())
1069                        + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1070       }
1071       Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1072       for(int i = 0; i < tmpfstates.size(); ++i) {
1073         FlagState tmpFState = tmpfstates.elementAt(i);
1074
1075         if(this.currentSchedule.getAllyCoreTable() == null) {
1076           isolate = true;
1077         } else {
1078           isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
1079                     (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
1080         }
1081
1082         Vector<Integer> sendto = new Vector<Integer>();
1083         Queue<Integer> queue = null;
1084         if(targetCoreTbl != null) {
1085           queue = targetCoreTbl.get(tmpFState);
1086         }
1087         if((queue != null) &&
1088            ((queue.size() != 1) ||
1089             ((queue.size() == 1) && (queue.element().intValue() != num)))) {
1090           // this object may be transferred to other cores
1091           String queuename = (String) this.fsate2qnames[num].get(tmpFState);
1092           String queueins = queuename + "ins";
1093
1094           Object[] cores = queue.toArray();
1095           String index = "0";
1096           Integer targetcore = (Integer)cores[0];
1097           if(queue.size() > 1) {
1098             index = queueins + ".index";
1099           }
1100           if(queue.size() > 1) {
1101             output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
1102             for(int k = 0; k < cores.length; ++k) {
1103               output.println("case " + k + ":");
1104               targetcore = (Integer)cores[k];
1105               if(targetcore.intValue() == num) {
1106                 output.println("/* reside on this core*/");
1107                 if(isolate) {
1108                   output.println("{");
1109                   QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1110                   output.println("enqueueObject("+generateTemp(fm, temp)+", " + qinfo.qname +
1111                                  ", " + qinfo.length + ");");
1112                   output.println("}");
1113                 } /*else {
1114                   // TODO
1115                   // really needed?
1116                   output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1117                   output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1118                 }*/  // deleted 09/07/06, multi-param tasks are pinned to one core now
1119               } else {
1120                 /*if(!isolate) {
1121                   // TODO
1122                   // Is it possible to decide the actual queues?
1123                   output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1124                   output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1125                 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1126                 output.println("/* transfer to core " + targetcore.toString() + "*/");
1127                 output.println("{");
1128                 // enqueue this object and its destinations for later process
1129                 // all the possible queues
1130                 QueueInfo qinfo = null;
1131                 TranObjInfo tmpinfo = new TranObjInfo();
1132                 tmpinfo.name = generateTemp(fm, temp);
1133                 tmpinfo.targetcore = targetcore;
1134                 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1135                 if(targetFS != null) {
1136                   tmpinfo.fs = targetFS;
1137                 } else {
1138                   tmpinfo.fs = tmpFState;
1139                 }
1140                   qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1141                   output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1142                   output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1143                   output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1144                   output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1145                   output.println("tmpObjInfo->length = " + qinfo.length + ";");
1146                   output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1147                 output.println("}");
1148               }
1149               output.println("break;");
1150             }
1151             output.println("}");
1152           } else {
1153             /*if(!isolate) {
1154               // TODO
1155               // Is it possible to decide the actual queues?
1156               output.println("/* possibly needed by multi-parameter tasks on this core*//*");
1157               output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1158             }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1159             output.println("/* transfer to core " + targetcore.toString() + "*/");
1160             output.println("{");
1161             // enqueue this object and its destinations for later process
1162             // all the possible queues
1163             QueueInfo qinfo = null;
1164             TranObjInfo tmpinfo = new TranObjInfo();
1165             tmpinfo.name = generateTemp(fm, temp);
1166             tmpinfo.targetcore = targetcore;
1167             FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1168             if(targetFS != null) {
1169               tmpinfo.fs = targetFS;
1170             } else {
1171               tmpinfo.fs = tmpFState;
1172             }
1173               qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1174               output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1175               output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1176               output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1177               output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1178               output.println("tmpObjInfo->length = " + qinfo.length + ";");
1179               output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1180             output.println("}");
1181           }
1182           output.println("/* increase index*/");
1183           output.println("++" + queueins + ".index;");
1184         } else {
1185           // this object will reside on current core
1186           output.println("/* reside on this core*/");
1187           if(isolate) {
1188             output.println("{");
1189             QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1190             output.println("enqueueObject("+generateTemp(fm, temp)+", " + qinfo.qname +
1191                            ", " + qinfo.length + ");");
1192             output.println("}");
1193           } /*else {
1194             // TODO
1195             // really needed?
1196             output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1197           }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1198         }
1199
1200         // codes for multi-params tasks
1201         if(!isolate) {
1202           // flagstate associated with some multi-params tasks
1203           // need to be send to other cores
1204           Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1205           output.println("/* send the shared object to possible queues on other cores*/");
1206           // TODO, temporary solution, send to mostly the first two 
1207           int upperbound = targetcores.size() > 2? 2: targetcores.size();
1208           for(int k = 0; k < upperbound; ++k) {
1209             // TODO
1210             // add the information of exactly which queue
1211             int targetcore = targetcores.elementAt(k).intValue();
1212             if(!sendto.contains(targetcore)) {
1213             // previously not sended to this target core
1214             // enqueue this object and its destinations for later process
1215             output.println("{");
1216             // all the possible queues
1217             QueueInfo qinfo = null;
1218             TranObjInfo tmpinfo = new TranObjInfo();
1219             tmpinfo.name = generateTemp(fm, temp);
1220             tmpinfo.targetcore = targetcore;
1221             FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1222             if(targetFS != null) {
1223               tmpinfo.fs = targetFS;
1224             } else {
1225               tmpinfo.fs = tmpFState;
1226             }
1227               qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1228               output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1229               output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1230               output.println("tmpObjInfo->targetcore = "+targetcore+";");
1231               output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1232               output.println("tmpObjInfo->length = " + qinfo.length + ";");
1233               output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1234               output.println("}");
1235               sendto.addElement(targetcore);
1236             }
1237           }
1238         }
1239       }
1240
1241       if(initfstates != null) {
1242         output.println("}");
1243       }
1244     }
1245   }
1246
1247   protected QueueInfo outputqueues(FlagState tmpFState, 
1248                                  int num, 
1249                                  PrintWriter output, 
1250                                  boolean isEnqueue) {
1251     // queue array
1252     QueueInfo qinfo = new QueueInfo();
1253     qinfo.qname  = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1254     output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1255     Iterator it_edges = tmpFState.getEdgeVector().iterator();
1256     Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1257     Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1258     Vector<Integer> indexes = new Vector<Integer>();
1259     boolean comma = false;
1260     qinfo.length = 0;
1261     while(it_edges.hasNext()) {
1262       FEdge fe = (FEdge)it_edges.next();
1263       TaskDescriptor td = fe.getTask();
1264       int paraindex = fe.getIndex();
1265       if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1266         if((!tasks.contains(td)) ||
1267            ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1268           tasks.addElement(td);
1269           indexes.addElement(paraindex);
1270           if(comma) {
1271             output.println(",");
1272           } else {
1273             comma = true;
1274           }
1275           output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1276           ++qinfo.length;
1277         }
1278       }
1279     }
1280     output.println("};");
1281     return qinfo;
1282   }
1283
1284   protected QueueInfo outputtransqueues(FlagState tmpFState, 
1285                                       int targetcore, 
1286                                       PrintWriter output) {
1287     // queue array
1288     QueueInfo qinfo = new QueueInfo();
1289     qinfo.qname  = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1290     output.println("int " + qinfo.qname + "_clone[] = {");
1291     Iterator it_edges = tmpFState.getEdgeVector().iterator();
1292     Vector<TaskDescriptor> residetasks = this.scheduling.get(targetcore).getTasks();
1293     Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1294     Vector<Integer> indexes = new Vector<Integer>();
1295     boolean comma = false;
1296     qinfo.length = 0;
1297     while(it_edges.hasNext()) {
1298       FEdge fe = (FEdge)it_edges.next();
1299       TaskDescriptor td = fe.getTask();
1300       int paraindex = fe.getIndex();
1301       if(residetasks.contains(td)) {
1302         if((!tasks.contains(td)) ||
1303            ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1304           tasks.addElement(td);
1305           indexes.addElement(paraindex);
1306           if(comma) {
1307             output.println(",");
1308           } else {
1309             comma = true;
1310           }
1311           output.print(residetasks.indexOf(td) + ", ");
1312           output.print(paraindex);
1313           ++qinfo.length;
1314         }
1315       }
1316     }
1317     output.println("};");
1318     output.println("int * " + qinfo.qname + " = RUNMALLOC(sizeof(int) * " + qinfo.length * 2 + ");");
1319     output.println("memcpy(" + qinfo.qname + ", (int *)" + qinfo.qname + "_clone, sizeof(int) * " + qinfo.length * 2 + ");");
1320     return qinfo;
1321   }
1322
1323   protected class QueueInfo {
1324     public int length;
1325     public String qname;
1326   }
1327
1328   protected String generateTempFlagName(FlatMethod fm, 
1329                                       TempDescriptor td) {
1330     MethodDescriptor md=fm.getMethod();
1331     TaskDescriptor task=fm.getTask();
1332     TempObject objecttemps=(TempObject) tempstable.get(md!=null ? md : task);
1333
1334     if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1335       return td.getSafeSymbol() + "_oldflag";
1336     }
1337
1338     if (objecttemps.isLocalPtr(td)) {
1339       return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1340     }
1341
1342     if (objecttemps.isParamPtr(td)) {
1343       return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1344     }
1345     throw new Error();
1346   }
1347
1348   protected void outputTransCode(PrintWriter output) {
1349     output.println("while(0 == isEmpty(totransobjqueue)) {");
1350     output.println("   struct transObjInfo * totransobj = (struct transObjInfo *)(getItem(totransobjqueue));");
1351     output.println("   transferObject(totransobj);");
1352     output.println("   RUNFREE(totransobj->queues);");
1353     output.println("   RUNFREE(totransobj);");
1354     output.println("}");
1355     //output.println("freeQueue(totransobjqueue);");
1356   }
1357
1358   protected void outputAliasLockCode(FlatMethod fm, 
1359                                          PrintWriter output) {
1360     if(this.m_oa == null) {
1361       return;
1362     }
1363     TaskDescriptor td = fm.getTask();
1364     Object[] allocSites = this.m_oa.getFlaggedAllocationSitesReachableFromTask(td).toArray();
1365     Vector<Vector<Integer>> aliasSets = new Vector<Vector<Integer>>();
1366     Vector<Vector<FlatNew>> aliasFNSets = new Vector<Vector<FlatNew>>();
1367     Hashtable<Integer, Vector<FlatNew>> aliasFNTbl4Para = new Hashtable<Integer, Vector<FlatNew>>();
1368     Hashtable<FlatNew, Vector<FlatNew>> aliasFNTbl = new Hashtable<FlatNew, Vector<FlatNew>>();
1369     Set<HeapRegionNode> common;
1370     for( int i = 0; i < fm.numParameters(); ++i ) {
1371       // for the ith parameter check for aliases to all
1372       // higher numbered parameters
1373       aliasSets.add(null);
1374       for( int j = i + 1; j < fm.numParameters(); ++j ) {
1375         common = this.m_oa.createsPotentialAliases(td, i, j);
1376         if(!common.isEmpty()) {
1377       // ith parameter and jth parameter has alias, create lock to protect them
1378           if(aliasSets.elementAt(i) == null) {
1379             aliasSets.setElementAt(new Vector<Integer>(), i);
1380           }
1381           aliasSets.elementAt(i).add(j);
1382         }
1383       }
1384
1385       // for the ith parameter, check for aliases against
1386       // the set of allocation sites reachable from this
1387       // task context
1388       aliasFNSets.add(null);
1389       for(int j = 0; j < allocSites.length; j++) {
1390         AllocationSite as = (AllocationSite)allocSites[j];
1391         common = this.m_oa.createsPotentialAliases(td, i, as);
1392         if( !common.isEmpty() ) {
1393       // ith parameter and allocationsite as has alias
1394           if(aliasFNSets.elementAt(i) == null) {
1395             aliasFNSets.setElementAt(new Vector<FlatNew>(), i);
1396           }
1397           aliasFNSets.elementAt(i).add(as.getFlatNew());
1398         }
1399       }
1400     }
1401
1402     // for each allocation site check for aliases with
1403     // other allocation sites in the context of execution
1404     // of this task
1405     for( int i = 0; i < allocSites.length; ++i ) {
1406       AllocationSite as1 = (AllocationSite)allocSites[i];
1407       for(int j = i + 1; j < allocSites.length; j++) {
1408         AllocationSite as2 = (AllocationSite)allocSites[j];
1409
1410         common = this.m_oa.createsPotentialAliases(td, as1, as2);
1411         if( !common.isEmpty() ) {
1412       // as1 and as2 has alias
1413           if(!aliasFNTbl.containsKey(as1.getFlatNew())) {
1414             aliasFNTbl.put(as1.getFlatNew(), new Vector<FlatNew>());
1415           }
1416           if(!aliasFNTbl.get(as1.getFlatNew()).contains(as2.getFlatNew())) {
1417             aliasFNTbl.get(as1.getFlatNew()).add(as2.getFlatNew());
1418           }
1419         }
1420       }
1421     }
1422
1423     // if FlatNew N1->N2->N3, we group N1, N2, N3 together
1424     Iterator<FlatNew> it = aliasFNTbl.keySet().iterator();
1425     Vector<FlatNew> visited = new Vector<FlatNew>();
1426     while(it.hasNext()) {
1427       FlatNew tmpfn = it.next();
1428       if(visited.contains(tmpfn)) {
1429         continue;
1430       }
1431       visited.add(tmpfn);
1432       Queue<FlatNew> tovisit = new LinkedList<FlatNew>();
1433       Vector<FlatNew> tmpv = aliasFNTbl.get(tmpfn);
1434       if(tmpv == null) {
1435         continue;
1436       }
1437
1438       for(int j = 0; j < tmpv.size(); j++) {
1439         tovisit.add(tmpv.elementAt(j));
1440       }
1441
1442       while(!tovisit.isEmpty()) {
1443         FlatNew fn = tovisit.poll();
1444         visited.add(fn);
1445         Vector<FlatNew> tmpset = aliasFNTbl.get(fn);
1446         if(tmpset != null) {
1447           // merge tmpset to the alias set of the ith parameter
1448           for(int j = 0; j < tmpset.size(); j++) {
1449             if(!tmpv.contains(tmpset.elementAt(j))) {
1450               tmpv.add(tmpset.elementAt(j));
1451               tovisit.add(tmpset.elementAt(j));
1452             }
1453           }
1454           aliasFNTbl.remove(fn);
1455         }
1456       }
1457       it = aliasFNTbl.keySet().iterator();
1458     }
1459
1460     // check alias between parameters and between parameter-flatnew
1461     for(int i = 0; i < aliasSets.size(); i++) {
1462       Queue<Integer> tovisit = new LinkedList<Integer>();
1463       Vector<Integer> tmpv = aliasSets.elementAt(i);
1464       if(tmpv == null) {
1465         continue;
1466       }
1467
1468       for(int j = 0; j < tmpv.size(); j++) {
1469         tovisit.add(tmpv.elementAt(j));
1470       }
1471
1472       while(!tovisit.isEmpty()) {
1473         int index = tovisit.poll().intValue();
1474         Vector<Integer> tmpset = aliasSets.elementAt(index);
1475         if(tmpset != null) {
1476           // merge tmpset to the alias set of the ith parameter
1477           for(int j = 0; j < tmpset.size(); j++) {
1478             if(!tmpv.contains(tmpset.elementAt(j))) {
1479               tmpv.add(tmpset.elementAt(j));
1480               tovisit.add(tmpset.elementAt(j));
1481             }
1482           }
1483           aliasSets.setElementAt(null, index);
1484         }
1485
1486         Vector<FlatNew> tmpFNSet = aliasFNSets.elementAt(index);
1487         if(tmpFNSet != null) {
1488           // merge tmpFNSet to the aliasFNSet of the ith parameter
1489           if(aliasFNSets.elementAt(i) == null) {
1490             aliasFNSets.setElementAt(tmpFNSet, i);
1491           } else {
1492             Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1493             for(int j = 0; j < tmpFNSet.size(); j++) {
1494               if(!tmpFNv.contains(tmpFNSet.elementAt(j))) {
1495                 tmpFNv.add(tmpFNSet.elementAt(j));
1496               }
1497             }
1498           }
1499           aliasFNSets.setElementAt(null, index);
1500         }
1501       }
1502     }
1503
1504     int numlock = 0;
1505     int numparalock = 0;
1506     Vector<Vector<Integer>> tmpaliasSets = new Vector<Vector<Integer>>();
1507     for(int i = 0; i < aliasSets.size(); i++) {
1508       Vector<Integer> tmpv = aliasSets.elementAt(i);
1509       if(tmpv != null) {
1510         tmpv.add(0, i);
1511         tmpaliasSets.add(tmpv);
1512         numlock++;
1513       }
1514
1515       Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1516       if(tmpFNv != null) {
1517         aliasFNTbl4Para.put(i, tmpFNv);
1518         if(tmpv == null) {
1519           numlock++;
1520         }
1521       }
1522     }
1523     numparalock = numlock;
1524     aliasSets.clear();
1525     aliasSets = null;
1526     this.m_aliasSets = tmpaliasSets;
1527     aliasFNSets.clear();
1528     aliasFNSets = null;
1529     this.m_aliasFNTbl4Para = aliasFNTbl4Para;
1530     this.m_aliasFNTbl = aliasFNTbl;
1531     numlock += this.m_aliasFNTbl.size();
1532
1533     // create locks
1534     if(numlock > 0) {
1535       output.println("int aliaslocks[" + numlock + "];");
1536       output.println("int tmpi = 0;");      
1537       // associate locks with parameters
1538       int lockindex = 0;
1539       for(int i = 0; i < this.m_aliasSets.size(); i++) {
1540         Vector<Integer> toadd = this.m_aliasSets.elementAt(i);
1541
1542         output.println("int tmplen_" + lockindex + " = " + toadd.size());
1543         output.println("void * tmpptrs_" + lockindex + "[] = {");
1544         for(int j = 0; j < toadd.size(); j++) {
1545           int para = toadd.elementAt(j).intValue();
1546           output.print(generateTemp(fm, fm.getParameter(para)));
1547           if(j < toadd.size() - 1) {
1548             output.print(", ");
1549           } else {
1550             output.println("};");
1551           }
1552         }
1553         output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", tmplen_" + lockindex + ", lockRedirectTbl);");
1554
1555         for(int j = 0; j < toadd.size(); j++) {
1556           int para = toadd.elementAt(j).intValue();
1557           output.println("addAliasLock("  + generateTemp(fm, fm.getParameter(para)) + ", aliaslocks[" + i + "]);");
1558         }
1559         // check if this lock is also associated with any FlatNew nodes
1560         if(this.m_aliasFNTbl4Para.containsKey(toadd.elementAt(0))) {
1561           if(this.m_aliaslocksTbl4FN == null) {
1562             this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1563           }
1564           Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(toadd.elementAt(0));
1565           for(int j = 0; j < tmpv.size(); j++) {
1566             FlatNew fn = tmpv.elementAt(j);
1567             if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1568               this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1569             }
1570             this.m_aliaslocksTbl4FN.get(fn).add(i);
1571           }
1572           this.m_aliasFNTbl4Para.remove(toadd.elementAt(0));
1573         }
1574         lockindex++;
1575       }
1576       
1577       Object[] key = this.m_aliasFNTbl4Para.keySet().toArray();
1578       for(int i = 0; i < key.length; i++) {
1579         int para = ((Integer)key[i]).intValue();
1580
1581         output.println("void * tmpptrs_" + lockindex + "[] = {" + generateTemp(fm, fm.getParameter(para)) + "};");
1582         output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", 1, lockRedirectTbl);");
1583         
1584         output.println("addAliasLock(" + generateTemp(fm, fm.getParameter(para)) + ", aliaslocks[" + lockindex + "]);");
1585         Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(para);
1586         for(int j = 0; j < tmpv.size(); j++) {
1587           FlatNew fn = tmpv.elementAt(j);
1588           if(this.m_aliaslocksTbl4FN == null) {
1589             this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1590           }
1591           if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1592             this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1593           }
1594           this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1595         }
1596         lockindex++;
1597       }
1598       
1599       // check m_aliasFNTbl for locks associated with FlatNew nodes
1600       Object[] FNkey = this.m_aliasFNTbl.keySet().toArray();
1601       for(int i = 0; i < FNkey.length; i++) {
1602         FlatNew fn = (FlatNew)FNkey[i];
1603         Vector<FlatNew> tmpv = this.m_aliasFNTbl.get(fn);
1604         
1605         output.println("aliaslocks[tmpi++] = (int)(RUNMALLOC(sizeof(int)));");
1606         
1607         if(this.m_aliaslocksTbl4FN == null) {
1608           this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1609         }
1610         if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1611           this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1612         }
1613         this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1614         for(int j = 0; j < tmpv.size(); j++) {
1615           FlatNew tfn = tmpv.elementAt(j);
1616           if(!this.m_aliaslocksTbl4FN.containsKey(tfn)) {
1617             this.m_aliaslocksTbl4FN.put(tfn, new Vector<Integer>());
1618           }
1619           this.m_aliaslocksTbl4FN.get(tfn).add(lockindex);
1620         }
1621         lockindex++;
1622       }
1623     }
1624   }
1625
1626   protected void generateFlatReturnNode(FlatMethod fm, 
1627                                         FlatReturnNode frn, 
1628                                         PrintWriter output) {
1629     if (frn.getReturnTemp()!=null) {
1630       if (frn.getReturnTemp().getType().isPtr())
1631         output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp())+";");
1632       else
1633         output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
1634     } else {
1635       if(fm.getTask() != null) {
1636         output.println("#ifdef CACHEFLUSH");
1637         output.println("BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();");
1638         output.println("#ifdef DEBUG");
1639         output.println("BAMBOO_DEBUGPRINT(0xec00);");
1640         output.println("#endif");
1641         output.println("BAMBOO_CACHE_FLUSH_ALL();");
1642         output.println("#ifdef DEBUG");
1643         output.println("BAMBOO_DEBUGPRINT(0xecff);");
1644         output.println("#endif");
1645         output.println("BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();");
1646         output.println("#endif");
1647         outputTransCode(output);
1648       }
1649       output.println("return;");
1650     }
1651   }
1652
1653   protected void generateFlatNew(FlatMethod fm, 
1654                                  FlatNew fn,
1655                                  PrintWriter output) {
1656     if (fn.getType().isArray()) {
1657       int arrayid = state.getArrayNumber(fn.getType())
1658                     + state.numClasses();
1659       if (fn.isGlobal()) {
1660         output.println(generateTemp(fm, fn.getDst())
1661                        + "=allocate_newarrayglobal(trans, " + arrayid + ", "
1662                        + generateTemp(fm, fn.getSize()) + ");");
1663       } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1664         output.println(generateTemp(fm, fn.getDst())
1665                        + "=allocate_newarray(&" + localsprefix + ", "
1666                        + arrayid + ", " + generateTemp(fm, fn.getSize())
1667                        + ");");
1668       } else {
1669         output.println(generateTemp(fm, fn.getDst())
1670                        + "=allocate_newarray(" + arrayid + ", "
1671                        + generateTemp(fm, fn.getSize()) + ");");
1672       }
1673     } else {
1674       if (fn.isGlobal()) {
1675         output.println(generateTemp(fm, fn.getDst())
1676                        + "=allocate_newglobal(trans, "
1677                        + fn.getType().getClassDesc().getId() + ");");
1678       } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
1679         output.println(generateTemp(fm, fn.getDst())
1680                        + "=allocate_new(&" + localsprefix + ", "
1681                        + fn.getType().getClassDesc().getId() + ");");
1682       } else {
1683         output.println(generateTemp(fm, fn.getDst())
1684                        + "=allocate_new("
1685                        + fn.getType().getClassDesc().getId() + ");");
1686       }
1687     }
1688     // create alias lock if necessary
1689     if((this.m_aliaslocksTbl4FN != null) && (this.m_aliaslocksTbl4FN.containsKey(fn))) {
1690       Vector<Integer> tmpv = this.m_aliaslocksTbl4FN.get(fn);
1691       for(int i = 0; i < tmpv.size(); i++) {
1692         output.println("addAliasLock(" + generateTemp(fm, fn.getDst()) + ", aliaslocks[" + tmpv.elementAt(i).intValue() + "]);");
1693       }
1694     }
1695     // generate codes for profiling, recording how many new objects are created
1696     if(!fn.getType().isArray() && 
1697             (fn.getType().getClassDesc() != null) 
1698             && (fn.getType().getClassDesc().hasFlags())) {
1699         output.println("#ifdef PROFILE");
1700         output.println("addNewObjInfo(\"" + fn.getType().getClassDesc().getSymbol() + "\");");
1701         output.println("#endif");
1702     }
1703   }
1704
1705   class TranObjInfo {
1706     public String name;
1707     public int targetcore;
1708     public FlagState fs;
1709   }
1710
1711   protected boolean contains(Vector<TranObjInfo> sendto, 
1712                            TranObjInfo t) {
1713     if(sendto.size() == 0) {
1714       return false;
1715     }
1716     for(int i = 0; i < sendto.size(); i++) {
1717       TranObjInfo tmp = sendto.elementAt(i);
1718       if(!tmp.name.equals(t.name)) {
1719         return false;
1720       }
1721       if(tmp.targetcore != t.targetcore) {
1722         return false;
1723       }
1724       if(tmp.fs != t.fs) {
1725         return false;
1726       }
1727     }
1728     return true;
1729   }
1730 }