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