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;
11 import java.util.Vector;
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;
24 import IR.FlagDescriptor;
25 import IR.MethodDescriptor;
27 import IR.TagVarDescriptor;
28 import IR.TaskDescriptor;
29 import IR.TypeDescriptor;
31 import IR.VarDescriptor;
32 import IR.Tree.DNFFlag;
33 import IR.Tree.DNFFlagAtom;
34 import IR.Tree.FlagExpressionNode;
35 import IR.Tree.TagExpressionList;
37 public class BuildCodeMultiCore extends BuildCode {
38 private Vector<Schedule> scheduling;
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
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;
59 public BuildCodeMultiCore(State st,
63 Vector<Schedule> scheduling,
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;
75 // sometimes there are extra cores then needed in scheduling
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();
86 this.m_aliasSets = null;
87 this.m_aliasFNTbl4Para = null;
88 this.m_aliasFNTbl = null;
89 this.m_aliaslocksTbl4FN = null;
92 public void setOwnershipAnalysis(OwnershipAnalysis m_oa) {
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;
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);
119 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
120 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
123 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
124 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
127 /*if (state.structfile!=null) {
128 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
130 } catch (Exception e) {
135 /* Fix field safe symbols due to shadowing */
136 FieldShadow.handleFieldShadow(state);
138 /* Build the virtual dispatch tables */
140 buildVirtualTables(outvirtual);
142 /* Tag the methods that are invoked by static blocks */
143 tagMethodInvokedByStaticBlock();
145 /* Output includes */
146 outmethodheader.println("#ifndef METHODHEADERS_H");
147 outmethodheader.println("#define METHODHEADERS_H");
148 outmethodheader.println("#include \"structdefs.h\"");
150 outmethodheader.println("#include \"dstm.h\"");*/
152 /* Output Structures */
153 outputStructs(outstructs);
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;");
163 outglobaldefsprim.println("#ifndef __GLOBALDEFPRIM_H_");
164 outglobaldefsprim.println("#define __GLOBALDEFPRIM_H_");
165 outglobaldefsprim.println("");
166 outglobaldefsprim.println("struct global_defsprim_t {");
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);
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);
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();
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();
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();
208 generateTaskStructs(outstructs, outmethodheader);
210 /* Outputs generic task structures if this is a task
212 outputTaskTypes(outtask);
215 /* Build the actual methods */
216 outputMethods(outmethod);
219 Iterator[] taskits = new Iterator[this.coreNum];
220 for(int i = 0; i < taskits.length; ++i) {
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);
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) {
237 outtaskdefs.println(",");
241 outtaskdefs.println("/* object queue array for core " + i + "*/");
242 outtaskdefs.print("{");
244 for(int j = 0; j < numclasses; ++j) {
246 outtaskdefs.println(",");
250 outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
252 outtaskdefs.print("}");
254 outtaskdefs.println("};");
256 outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
257 for(int i = 0; i < numqueues.length; ++i) {
259 outtaskdefs.println(",");
263 int[] tmparray = numqueues[i];
265 outtaskdefs.print("{");
266 for(int j = 0; j < tmparray.length; ++j) {
268 outtaskdefs.print(",");
272 outtaskdefs.print(tmparray[j]);
274 outtaskdefs.print("}");
276 outtaskdefs.println("};");
278 /* parameter queue arrays for all the tasks*/
279 outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
281 for(int i = 0; i < this.coreNum; ++i) {
283 outtaskdefs.println(",");
287 outtaskdefs.println("/* parameter queue array for core " + i + "*/");
288 outtaskdefs.print(this.coreqarrayprefix + i);
290 outtaskdefs.println("};");
292 for(int i = 0; i < taskits.length; ++i) {
293 outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
294 Iterator taskit = taskits[i];
297 while(taskit.hasNext()) {
298 TaskDescriptor td=(TaskDescriptor)taskit.next();
302 outtaskdefs.println(",");
303 outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
306 outtaskdefs.println();
307 outtaskdefs.println("};");
309 outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
311 for(int i = 0; i < taskits.length; ++i) {
313 outtaskdefs.println(",");
316 outtaskdefs.print(this.taskarrayprefix + i);
318 outtaskdefs.println("};");
320 outtaskdefs.print("int numtasks[]= {");
322 for(int i = 0; i < taskits.length; ++i) {
324 outtaskdefs.print(",");
327 outtaskdefs.print(numtasks[i]);
329 outtaskdefs.println("};");
330 outtaskdefs.println("int corenum=0;");
333 outtask.println("#endif");
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);
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();
361 /* Output structure definitions for repair tool */
362 /*if (state.structfile!=null) {
363 buildRepairStructs(outrepairstructs);
364 outrepairstructs.close();
367 outputInitStaticAndGlobalMethod(outmethod);
370 outmethodheader.println("#endif");
371 outmethodheader.close();
373 outstructs.println("#endif");
377 private void outputInitStaticAndGlobalMethod(PrintWriter outmethod) {
378 outmethod.println("void initStaticAndGlobal() {");
379 outmethod.println(" int i;");
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(" }");
389 outputClassObjects(outmethod);
390 outputStaticBlocks(outmethod);
392 outmethod.println("}");
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 */
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();
407 while(taskit.hasNext()) {
408 /* Classify parameters */
409 TaskDescriptor task=taskit.next();
410 FlatMethod fm=state.getMethodFlat(task);
411 generateTempStructs(fm);
413 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
414 TempObject objecttemps=(TempObject) tempstable.get(task);
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()+";");
426 output.println("};\n");
427 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
428 maxtaskparams=objectparams.numPointers()+fm.numTags();
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()+";");
445 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
447 output.println("};\n");
450 /* Output task declaration */
451 headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
453 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
454 headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
456 headersout.print("void * parameterarray[]");
457 headersout.println(");\n");
463 /* This method outputs code for each task. */
465 protected void outputTaskCode(PrintWriter outtaskdefs,
466 PrintWriter outmethod,
471 /* Compile task based program */
472 outtaskdefs.println("#include \"task.h\"");
473 outtaskdefs.println("#include \"methodheaders.h\"");
475 /* Output object transfer queues into method.c*/
476 generateObjectTransQueues(outmethod);
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) {
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);
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 + "[] = {");
499 Vector tmpvector = qnames[i];
500 if(tmpvector != null) {
501 for(int j = 0; j < tmpvector.size(); ++j) {
503 outtaskdefs.println(",");
507 outtaskdefs.print("&" + tmpvector.elementAt(j));
509 numqueues[num][i] = tmpvector.size();
511 numqueues[num][i] = 0;
513 outtaskdefs.println("};");
516 /* All the queues for tasks residing on this core*/
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()) {
523 outtaskdefs.println(",");
527 TaskDescriptor td=taskit.next();
528 outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
530 outtaskdefs.println("};");
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();
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");
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("};");
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("};");
580 outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
581 outtask.println("extern int numqueues[][NUMCLASSES];");
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("};");
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("};");
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[];");
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;
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();
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) {
639 output.print(((Integer)targetcores[j]).intValue());
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 + "};");
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();
659 //ParamsObject objectparams=(ParamsObject)paramstable.get(task);
660 generateTaskHeader(fm, task,output);
662 TempObject objecttemp=(TempObject) tempstable.get(task);
664 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
665 output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
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("};");
674 for(int i=0; i<objecttemp.numPrimitives(); i++) {
675 TempDescriptor td=objecttemp.getPrimitive(i);
676 TypeDescriptor type=td.getType();
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()+";");
684 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
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)+
693 /* Assign labels to FlatNode's if necessary.*/
695 Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm, null);
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+");");
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;");
708 this.m_aliasSets = null;
709 this.m_aliasFNTbl4Para = null;
710 this.m_aliasFNTbl = null;
711 this.m_aliaslocksTbl4FN = null;
712 outputAliasLockCode(fm, output);
714 /* generate print information for RAW version */
715 output.println("#ifdef MULTICORE");
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';");
726 output.println("#ifdef RAWPATH");
728 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
729 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
731 output.println("printf(\"(%x,%x) Process %x(%d): task %s\\n\", udn_tile_coord_x(), udn_tile_coord_y(), corenum, corenum, \"" + task.getSymbol() + "\");");
733 output.println("#endif");
734 output.println("#ifdef DEBUG");
736 output.println("BAMBOO_DEBUGPRINT(0xAAAA);");
737 output.println("BAMBOO_DEBUGPRINT_REG(tmpsum);");
739 output.println("printf(\"(%x,%x) Process %x(%d): task %s\\n\", udn_tile_coord_x(), udn_tile_coord_y(), corenum, corenum, \"" + task.getSymbol() + "\");");
741 output.println("#endif");
745 output.println("#endif");
747 for(int i = 0; i < fm.numParameters(); ++i) {
748 TempDescriptor temp = fm.getParameter(i);
749 output.println(" ++" + generateTemp(fm, temp)+"->version;");
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);
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();}");
770 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
772 if (current_node.numNext()==0) {
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;");
788 } else if(current_node.numNext()==1) {
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)+";");
796 current_node=nextnode;
797 } else if (current_node.numNext()==2) {
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))+";");
807 current_node=current_node.getNext(0);
808 } else throw new Error();
811 output.println("}\n\n");
814 /** This method outputs TaskDescriptor information */
815 protected void generateTaskDescriptor(PrintWriter output,
820 int num = this.currentSchedule.getCoreNum();
822 output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
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);
831 if (param_flag==null) {
832 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
833 output.println("0x0, 0x0 };");
836 DNFFlag dflag=param_flag.getDNF();
837 dnfterms=dflag.size();
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++) {
844 Vector term=dflag.get(j);
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();
856 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
858 output.println("};");
861 output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
862 //BUG...added next line to fix, test with any task program
864 for(int j=0; j<param_tag.numTags(); j++) {
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()));
875 output.println("};");
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;
882 if(qnames[param_type.getClassDesc().getId()] == null) {
883 qnames[param_type.getClassDesc().getId()] = new Vector();
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
893 output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
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
900 output.println("};");
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
910 output.println("/* number of tags */"+param_tag.numTags()+",");
912 output.println("/* number of tags */ 0,");
913 output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num)); // tagarray
914 output.println("};");
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++) {
922 output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
924 output.println("};");
926 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
927 for (int i=0; i<task.numParameters(); i++) {
930 output.print("¶meter_"+i+"_"+task.getCoreSafeSymbol(num));
932 output.println("};");
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("};");
946 /** This method generates header information for the task
947 * referenced by the Descriptor des. */
949 protected void generateTaskHeader(FlatMethod fm,
951 PrintWriter output) {
953 ParamsObject objectparams=(ParamsObject)paramstable.get(des);
954 TaskDescriptor task=(TaskDescriptor) des;
956 int num = this.currentSchedule.getCoreNum();
957 //catch the constructor case
958 output.print("void ");
959 output.print(task.getCoreSafeSymbol(num)+"(");
961 boolean printcomma=false;
962 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
963 output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
967 if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) {
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+"];");
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
981 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
982 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
983 } else output.println(") {");
986 protected void generateFlagOrAnd(FlatFlagActionNode ffan,
992 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
993 output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
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("}");
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");
1016 protected void generateObjectDistribute(FlatFlagActionNode ffan,
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);
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);
1033 if(!fs.isSetmask()) {
1034 Hashtable flags=(Hashtable)flagorder.get(cd);
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();
1044 fs.setAndmask(andmask);
1045 fs.setCheckmask(checkmask);
1046 fs.setSetmask(true);
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()) + ")) {");
1060 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1061 for(int i = 0; i < tmpfstates.size(); ++i) {
1062 FlagState tmpFState = tmpfstates.elementAt(i);
1064 // may have bugs here
1065 output.println("/* reside on this core*");
1066 output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1068 if(initfstates != null) {
1069 output.println("}");
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()) + ")) {");
1084 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1085 for(int i = 0; i < tmpfstates.size(); ++i) {
1086 FlagState tmpFState = tmpfstates.elementAt(i);
1088 if(this.currentSchedule.getAllyCoreTable() == null) {
1091 isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
1092 (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
1095 Vector<Integer> sendto = new Vector<Integer>();
1096 Queue<Integer> queue = null;
1097 if(targetCoreTbl != null) {
1098 queue = targetCoreTbl.get(tmpFState);
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";
1107 Object[] cores = queue.toArray();
1109 Integer targetcore = (Integer)cores[0];
1110 if(queue.size() > 1) {
1111 index = queueins + ".index";
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*/");
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("}");
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
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;
1151 tmpinfo.fs = tmpFState;
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("}");
1162 output.println("break;");
1164 output.println("}");
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;
1184 tmpinfo.fs = tmpFState;
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("}");
1195 output.println("/* increase index*/");
1196 output.println("++" + queueins + ".index;");
1198 // this object will reside on current core
1199 output.println("/* reside on this core*/");
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("}");
1209 output.println("enqueueObject("+generateTemp(fm, temp)+", NULL, 0);");
1210 }*/ // deleted 09/07/06, multi-param tasks are pinned to one core now
1213 // codes for multi-params tasks
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) {
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;
1238 tmpinfo.fs = tmpFState;
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);
1254 if(initfstates != null) {
1255 output.println("}");
1260 protected QueueInfo outputqueues(FlagState tmpFState,
1263 boolean isEnqueue) {
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;
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);
1284 output.println(",");
1288 output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1293 output.println("};");
1297 protected QueueInfo outputtransqueues(FlagState tmpFState,
1299 PrintWriter output) {
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;
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);
1320 output.println(",");
1324 output.print(residetasks.indexOf(td) + ", ");
1325 output.print(paraindex);
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 + ");");
1336 protected class QueueInfo {
1338 public String qname;
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);
1347 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1348 return td.getSafeSymbol() + "_oldflag";
1351 if (objecttemps.isLocalPtr(td)) {
1352 return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1355 if (objecttemps.isParamPtr(td)) {
1356 return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
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);");
1371 protected void outputAliasLockCode(FlatMethod fm,
1372 PrintWriter output) {
1373 if(this.m_oa == null) {
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);
1394 aliasSets.elementAt(i).add(j);
1398 // for the ith parameter, check for aliases against
1399 // the set of allocation sites reachable from this
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);
1410 aliasFNSets.elementAt(i).add(as.getFlatNew());
1415 // for each allocation site check for aliases with
1416 // other allocation sites in the context of execution
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];
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>());
1429 if(!aliasFNTbl.get(as1.getFlatNew()).contains(as2.getFlatNew())) {
1430 aliasFNTbl.get(as1.getFlatNew()).add(as2.getFlatNew());
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)) {
1445 Queue<FlatNew> tovisit = new LinkedList<FlatNew>();
1446 Vector<FlatNew> tmpv = aliasFNTbl.get(tmpfn);
1451 for(int j = 0; j < tmpv.size(); j++) {
1452 tovisit.add(tmpv.elementAt(j));
1455 while(!tovisit.isEmpty()) {
1456 FlatNew fn = tovisit.poll();
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));
1467 aliasFNTbl.remove(fn);
1470 it = aliasFNTbl.keySet().iterator();
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);
1481 for(int j = 0; j < tmpv.size(); j++) {
1482 tovisit.add(tmpv.elementAt(j));
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));
1496 aliasSets.setElementAt(null, index);
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);
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));
1512 aliasFNSets.setElementAt(null, index);
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);
1524 tmpaliasSets.add(tmpv);
1528 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1529 if(tmpFNv != null) {
1530 aliasFNTbl4Para.put(i, tmpFNv);
1536 numparalock = numlock;
1539 this.m_aliasSets = tmpaliasSets;
1540 aliasFNSets.clear();
1542 this.m_aliasFNTbl4Para = aliasFNTbl4Para;
1543 this.m_aliasFNTbl = aliasFNTbl;
1544 numlock += this.m_aliasFNTbl.size();
1548 output.println("int aliaslocks[" + numlock + "];");
1549 output.println("int tmpi = 0;");
1550 // associate locks with parameters
1552 for(int i = 0; i < this.m_aliasSets.size(); i++) {
1553 Vector<Integer> toadd = this.m_aliasSets.elementAt(i);
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) {
1563 output.println("};");
1566 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", tmplen_" + lockindex + ", lockRedirectTbl);");
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 + "]);");
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>>();
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>());
1583 this.m_aliaslocksTbl4FN.get(fn).add(i);
1585 this.m_aliasFNTbl4Para.remove(toadd.elementAt(0));
1590 Object[] key = this.m_aliasFNTbl4Para.keySet().toArray();
1591 for(int i = 0; i < key.length; i++) {
1592 int para = ((Integer)key[i]).intValue();
1594 output.println("void * tmpptrs_" + lockindex + "[] = {" + generateTemp(fm, fm.getParameter(para)) + "};");
1595 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", 1, lockRedirectTbl);");
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>>();
1604 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1605 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1607 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
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);
1618 output.println("aliaslocks[tmpi++] = (int)(RUNMALLOC(sizeof(int)));");
1620 if(this.m_aliaslocksTbl4FN == null) {
1621 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1623 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1624 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
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>());
1632 this.m_aliaslocksTbl4FN.get(tfn).add(lockindex);
1639 protected void generateFlatReturnNode(FlatMethod fm,
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())+";");
1646 output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
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);
1658 output.println("return;");
1662 protected void generateFlatNew(FlatMethod fm,
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())
1678 output.println(generateTemp(fm, fn.getDst())
1679 + "=allocate_newarray(" + arrayid + ", "
1680 + generateTemp(fm, fn.getSize()) + ");");
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() + ");");
1692 output.println(generateTemp(fm, fn.getDst())
1694 + fn.getType().getClassDesc().getId() + ");");
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() + "]);");
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");
1716 public int targetcore;
1717 public FlagState fs;
1720 protected boolean contains(Vector<TranObjInfo> sendto,
1722 if(sendto.size() == 0) {
1725 for(int i = 0; i < sendto.size(); i++) {
1726 TranObjInfo tmp = sendto.elementAt(i);
1727 if(!tmp.name.equals(t.name)) {
1730 if(tmp.targetcore != t.targetcore) {
1733 if(tmp.fs != t.fs) {