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