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