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