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