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.Locality.LocalityBinding;
14 import Analysis.Scheduling.Schedule;
15 import Analysis.TaskStateAnalysis.FEdge;
16 import Analysis.TaskStateAnalysis.FlagState;
17 import Analysis.TaskStateAnalysis.SafetyAnalysis;
18 import Analysis.OwnershipAnalysis.AllocationSite;
19 import Analysis.OwnershipAnalysis.OwnershipAnalysis;
20 import Analysis.Prefetch.*;
21 import IR.ClassDescriptor;
23 import IR.FlagDescriptor;
24 import IR.MethodDescriptor;
26 import IR.TagVarDescriptor;
27 import IR.TaskDescriptor;
28 import IR.TypeDescriptor;
30 import IR.VarDescriptor;
31 import IR.Tree.DNFFlag;
32 import IR.Tree.DNFFlagAtom;
33 import IR.Tree.FlagExpressionNode;
34 import IR.Tree.TagExpressionList;
36 public class BuildCodeMultiCore extends BuildCode {
37 private Vector<Schedule> scheduling;
39 Schedule currentSchedule;
40 Hashtable[] fsate2qnames;
41 String objqarrayprefix= "objqueuearray4class";
42 String objqueueprefix = "objqueue4parameter_";
43 String paramqarrayprefix = "paramqueuearray4task";
44 String coreqarrayprefix = "paramqueuearrays_core";
45 String taskprefix = "task_";
46 String taskarrayprefix = "taskarray_core";
47 String otqueueprefix = "___otqueue";
48 int startupcorenum; // record the core containing startup task, suppose only one core can hava startup object
50 private OwnershipAnalysis m_oa;
51 private Vector<Vector<Integer>> m_aliasSets;
52 Hashtable<Integer, Vector<FlatNew>> m_aliasFNTbl4Para;
53 Hashtable<FlatNew, Vector<FlatNew>> m_aliasFNTbl;
54 Hashtable<FlatNew, Vector<Integer>> m_aliaslocksTbl4FN;
56 public BuildCodeMultiCore(State st,
60 Vector<Schedule> scheduling,
62 PrefetchAnalysis pa) {
63 super(st, temptovar, typeutil, sa, pa);
64 this.scheduling = scheduling;
65 this.coreNum = coreNum;
66 this.currentSchedule = null;
67 this.fsate2qnames = null;
68 this.startupcorenum = 0;
70 // sometimes there are extra cores then needed in scheduling
72 // currently, it is guaranteed that in scheduling, the corenum
73 // is started from 0 and continuous.
74 // MAY need modification here in the future when take hardware
75 // information into account.
76 if(this.scheduling.size() < this.coreNum) {
77 this.coreNum = this.scheduling.size();
81 this.m_aliasSets = null;
82 this.m_aliasFNTbl4Para = null;
83 this.m_aliasFNTbl = null;
84 this.m_aliaslocksTbl4FN = null;
87 public void setOwnershipAnalysis(OwnershipAnalysis m_oa) {
91 public void buildCode() {
92 /* Create output streams to write to */
93 PrintWriter outclassdefs=null;
94 PrintWriter outstructs=null;
95 PrintWriter outmethodheader=null;
96 PrintWriter outmethod=null;
97 PrintWriter outvirtual=null;
98 PrintWriter outtask=null;
99 PrintWriter outtaskdefs=null;
100 //PrintWriter outoptionalarrays=null;
101 //PrintWriter optionalheaders=null;
104 outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
105 outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
106 outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
107 outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
108 outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
110 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
111 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
114 outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
115 optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
118 /*if (state.structfile!=null) {
119 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
121 } catch (Exception e) {
126 /* Build the virtual dispatch tables */
127 super.buildVirtualTables(outvirtual);
129 /* Output includes */
130 outmethodheader.println("#ifndef METHODHEADERS_H");
131 outmethodheader.println("#define METHODHEADERS_H");
132 outmethodheader.println("#include \"structdefs.h\"");
134 outmethodheader.println("#include \"dstm.h\"");*/
136 /* Output Structures */
137 super.outputStructs(outstructs);
139 // Output the C class declarations
140 // These could mutually reference each other
141 super.outputClassDeclarations(outclassdefs);
143 // Output function prototypes and structures for parameters
144 Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
146 while(it.hasNext()) {
148 ClassDescriptor cn=(ClassDescriptor)it.next();
149 super.generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
151 outclassdefs.close();
154 /* Map flags to integers */
155 /* The runtime keeps track of flags using these integers */
156 it=state.getClassSymbolTable().getDescriptorsIterator();
157 while(it.hasNext()) {
158 ClassDescriptor cn=(ClassDescriptor)it.next();
162 generateTaskStructs(outstructs, outmethodheader);
164 /* Outputs generic task structures if this is a task
166 outputTaskTypes(outtask);
169 /* Build the actual methods */
170 super.outputMethods(outmethod);
173 Iterator[] taskits = new Iterator[this.coreNum];
174 for(int i = 0; i < taskits.length; ++i) {
177 int[] numtasks = new int[this.coreNum];
178 int[][] numqueues = new int[this.coreNum][numclasses];
179 /* Output code for tasks */
180 for(int i = 0; i < this.scheduling.size(); ++i) {
181 this.currentSchedule = this.scheduling.elementAt(i);
182 outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
185 // Output task descriptors
186 boolean comma = false;
187 outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
188 boolean needcomma = false;
189 for(int i = 0; i < numqueues.length ; ++i) {
191 outtaskdefs.println(",");
195 outtaskdefs.println("/* object queue array for core " + i + "*/");
196 outtaskdefs.print("{");
198 for(int j = 0; j < numclasses; ++j) {
200 outtaskdefs.println(",");
204 outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
206 outtaskdefs.print("}");
208 outtaskdefs.println("};");
210 outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
211 for(int i = 0; i < numqueues.length; ++i) {
213 outtaskdefs.println(",");
217 int[] tmparray = numqueues[i];
219 outtaskdefs.print("{");
220 for(int j = 0; j < tmparray.length; ++j) {
222 outtaskdefs.print(",");
226 outtaskdefs.print(tmparray[j]);
228 outtaskdefs.print("}");
230 outtaskdefs.println("};");
232 /* parameter queue arrays for all the tasks*/
233 outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
235 for(int i = 0; i < this.coreNum ; ++i) {
237 outtaskdefs.println(",");
241 outtaskdefs.println("/* parameter queue array for core " + i + "*/");
242 outtaskdefs.print(this.coreqarrayprefix + i);
244 outtaskdefs.println("};");
246 for(int i = 0; i < taskits.length; ++i) {
247 outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
248 Iterator taskit = taskits[i];
251 while(taskit.hasNext()) {
252 TaskDescriptor td=(TaskDescriptor)taskit.next();
256 outtaskdefs.println(",");
257 outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
260 outtaskdefs.println();
261 outtaskdefs.println("};");
263 outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
265 for(int i = 0; i < taskits.length; ++i) {
267 outtaskdefs.println(",");
270 outtaskdefs.print(this.taskarrayprefix + i);
272 outtaskdefs.println("};");
274 outtaskdefs.print("int numtasks[]= {");
276 for(int i = 0; i < taskits.length; ++i) {
278 outtaskdefs.print(",");
281 outtaskdefs.print(numtasks[i]);
283 outtaskdefs.println("};");
284 outtaskdefs.println("int corenum=0;");
287 outtask.println("#endif");
289 /* Record maximum number of task parameters */
290 outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
291 /* Record maximum number of all types, i.e. length of classsize[] */
292 outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays()));
293 /* Record number of cores */
294 outstructs.println("#define NUMCORES "+this.coreNum);
295 /* Record number of core containing startup task */
296 outstructs.println("#define STARTUPCORE "+this.startupcorenum);
297 } //else if (state.main!=null) {
298 /* Generate main method */
299 // outputMainMethod(outmethod);
302 /* Generate information for task with optional parameters */
303 /*if (state.TASK&&state.OPTIONAL){
304 generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
305 outoptionalarrays.close();
308 /* Output structure definitions for repair tool */
309 /*if (state.structfile!=null) {
310 buildRepairStructs(outrepairstructs);
311 outrepairstructs.close();
315 outmethodheader.println("#endif");
316 outmethodheader.close();
318 outstructs.println("#endif");
322 /** This function outputs (1) structures that parameters are
323 * passed in (when PRECISE GC is enabled) and (2) function
324 * prototypes for the tasks */
326 private void generateTaskStructs(PrintWriter output,
327 PrintWriter headersout) {
328 /* Cycle through tasks */
329 for(int i = 0; i < this.scheduling.size(); ++i) {
330 Schedule tmpschedule = this.scheduling.elementAt(i);
331 int num = tmpschedule.getCoreNum();
332 Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
334 while(taskit.hasNext()) {
335 /* Classify parameters */
336 TaskDescriptor task=taskit.next();
337 FlatMethod fm=state.getMethodFlat(task);
338 super.generateTempStructs(fm, null);
340 ParamsObject objectparams=(ParamsObject) paramstable.get(task);
341 TempObject objecttemps=(TempObject) tempstable.get(task);
343 /* Output parameter structure */
344 if (GENERATEPRECISEGC) {
345 output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
346 output.println(" int size;");
347 output.println(" void * next;");
348 for(int j=0; j<objectparams.numPointers(); j++) {
349 TempDescriptor temp=objectparams.getPointer(j);
350 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
353 output.println("};\n");
354 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
355 maxtaskparams=objectparams.numPointers()+fm.numTags();
359 /* Output temp structure */
360 if (GENERATEPRECISEGC) {
361 output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
362 output.println(" int size;");
363 output.println(" void * next;");
364 for(int j=0; j<objecttemps.numPointers(); j++) {
365 TempDescriptor temp=objecttemps.getPointer(j);
366 if (temp.getType().isNull())
367 output.println(" void * "+temp.getSafeSymbol()+";");
368 else if(temp.getType().isTag())
369 output.println(" struct "+
370 (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
372 output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
374 output.println("};\n");
377 /* Output task declaration */
378 headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
380 if (GENERATEPRECISEGC) {
381 headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
383 headersout.print("void * parameterarray[]");
384 headersout.println(");\n");
390 /* This method outputs code for each task. */
392 private void outputTaskCode(PrintWriter outtaskdefs,
393 PrintWriter outmethod,
398 /* Compile task based program */
399 outtaskdefs.println("#include \"task.h\"");
400 outtaskdefs.println("#include \"methodheaders.h\"");
402 /* Output object transfer queues into method.c*/
403 generateObjectTransQueues(outmethod);
405 //Vector[] qnames = new Vector[2];
406 int numclasses = numqueues[0].length;
407 Vector qnames[]= new Vector[numclasses];
408 for(int i = 0; i < qnames.length; ++i) {
411 Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
412 while(taskit.hasNext()) {
413 TaskDescriptor td=taskit.next();
414 FlatMethod fm=state.getMethodFlat(td);
415 generateTaskMethod(fm, null, outmethod);
416 generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
419 // generate queuearray for this core
420 int num = this.currentSchedule.getCoreNum();
421 boolean comma = false;
422 for(int i = 0; i < qnames.length; ++i) {
423 outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
424 outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
426 Vector tmpvector = qnames[i];
427 if(tmpvector != null) {
428 for(int j = 0; j < tmpvector.size(); ++j) {
430 outtaskdefs.println(",");
434 outtaskdefs.print("&" + tmpvector.elementAt(j));
436 numqueues[num][i] = tmpvector.size();
438 numqueues[num][i] = 0;
440 outtaskdefs.println("};");
443 /* All the queues for tasks residing on this core*/
445 outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
446 outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
447 taskit=this.currentSchedule.getTasks().iterator();
448 while(taskit.hasNext()) {
450 outtaskdefs.println(",");
454 TaskDescriptor td=taskit.next();
455 outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
457 outtaskdefs.println("};");
459 // record the iterator of tasks on this core
460 taskit=this.currentSchedule.getTasks().iterator();
461 taskits[num] = taskit;
462 numtasks[num] = this.currentSchedule.getTasks().size();
465 /** Prints out definitions for generic task structures */
466 private void outputTaskTypes(PrintWriter outtask) {
467 outtask.println("#ifndef _TASK_H");
468 outtask.println("#define _TASK_H");
469 outtask.println("#include \"ObjectHash.h\"");
470 outtask.println("#include \"structdefs.h\"");
471 outtask.println("#include \"Queue.h\"");
472 outtask.println("#include <string.h>");
473 outtask.println("#ifdef RAW");
474 outtask.println("#include <raw.h>");
475 outtask.println("#endif");
477 outtask.println("struct tagobjectiterator {");
478 outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
479 outtask.println(" struct ObjectIterator it; /* Object iterator */");
480 outtask.println(" struct ObjectHash * objectset;");
481 outtask.println("#ifdef OPTIONAL");
482 outtask.println(" int failedstate;");
483 outtask.println("#endif");
484 outtask.println(" int slot;");
485 outtask.println(" int tagobjindex; /* Index for tag or object depending on use */");
486 outtask.println(" /*if tag we have an object binding */");
487 outtask.println(" int tagid;");
488 outtask.println(" int tagobjectslot;");
489 outtask.println(" /*if object, we may have one or more tag bindings */");
490 outtask.println(" int numtags;");
491 outtask.println(" int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
492 outtask.println("};");
494 outtask.println("struct parameterwrapper {");
495 outtask.println(" //int type;");
496 outtask.println(" struct ObjectHash * objectset;");
497 outtask.println(" int numberofterms;");
498 outtask.println(" int * intarray;");
499 outtask.println(" int numbertags;");
500 outtask.println(" int * tagarray;");
501 outtask.println(" struct taskdescriptor * task;");
502 outtask.println(" int slot;");
503 outtask.println(" struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
504 outtask.println("};");
506 outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
507 outtask.println("extern int numqueues[][NUMCLASSES];");
509 outtask.println("struct parameterdescriptor {");
510 outtask.println(" int type;");
511 outtask.println(" int numberterms;");
512 outtask.println(" int *intarray;");
513 outtask.println(" struct parameterwrapper * queue;");
514 outtask.println(" int numbertags;");
515 outtask.println(" int *tagarray;");
516 outtask.println("};");
518 outtask.println("struct taskdescriptor {");
519 outtask.println(" void * taskptr;");
520 outtask.println(" int numParameters;");
521 outtask.println(" int numTotal;");
522 outtask.println(" struct parameterdescriptor **descriptorarray;");
523 outtask.println(" char * name;");
524 outtask.println("};");
526 outtask.println("extern struct taskdescriptor ** taskarray[];");
527 outtask.println("extern int numtasks[];");
528 outtask.println("extern int corenum;"); // define corenum to identify different core
529 outtask.println("extern struct parameterwrapper *** paramqueues[];");
533 private void generateObjectTransQueues(PrintWriter output) {
534 if(this.fsate2qnames == null) {
535 this.fsate2qnames = new Hashtable[this.coreNum];
536 for(int i = 0; i < this.fsate2qnames.length; ++i) {
537 this.fsate2qnames[i] = null;
540 int num = this.currentSchedule.getCoreNum();
541 assert(this.fsate2qnames[num] == null);
542 Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
543 this.fsate2qnames[num] = flag2qname;
544 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
545 if(targetCoreTbl != null) {
546 Object[] keys = targetCoreTbl.keySet().toArray();
548 output.println("/* Object transfer queues for core" + num + ".*/");
549 for(int i = 0; i < keys.length; ++i) {
550 FlagState tmpfstate = (FlagState)keys[i];
551 Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
552 String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
553 String queueins = queuename + "ins";
554 flag2qname.put(tmpfstate, queuename);
555 output.println("struct " + queuename + " {");
556 output.println(" int * cores;");
557 output.println(" int index;");
558 output.println(" int length;");
559 output.println("};");
560 output.print("int " + queuename + "cores[] = {");
561 for(int j = 0; j < targetcores.length; ++j) {
565 output.print(((Integer)targetcores[j]).intValue());
567 output.println("};");
568 output.println("struct " + queuename + " " + queueins + "= {");
569 output.println(/*".cores = " + */ queuename + "cores,");
570 output.println(/*".index = " + */ "0,");
571 output.println(/*".length = " +*/ targetcores.length + "};");
577 private void generateTaskMethod(FlatMethod fm,
579 PrintWriter output) {
580 /*if (State.PRINTFLAT)
581 System.out.println(fm.printMethod());*/
582 TaskDescriptor task=fm.getTask();
583 assert(task != null);
584 int num = this.currentSchedule.getCoreNum();
586 //ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:task);
587 generateTaskHeader(fm, lb, task,output);
588 TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : task);
589 /*if (state.DSM&&lb.getHasAtomic()) {
590 output.println("transrecord_t * trans;");
593 if (GENERATEPRECISEGC) {
594 output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
596 output.print(objecttemp.numPointers()+",");
597 output.print(paramsprefix);
598 for(int j=0; j<objecttemp.numPointers(); j++)
599 output.print(", NULL");
600 output.println("};");
603 for(int i=0; i<objecttemp.numPrimitives(); i++) {
604 TempDescriptor td=objecttemp.getPrimitive(i);
605 TypeDescriptor type=td.getType();
607 output.println(" void * "+td.getSafeSymbol()+";");
608 else if (type.isClass()||type.isArray())
609 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
611 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
614 for(int i = 0; i < fm.numParameters(); ++i) {
615 TempDescriptor temp = fm.getParameter(i);
616 output.println(" int "+generateTempFlagName(fm, temp, lb)+" = "+super.generateTemp(fm, temp, lb)+
620 /* Assign labels to FlatNode's if necessary.*/
622 Hashtable<FlatNode, Integer> nodetolabel=super.assignLabels(fm);
624 /* Check to see if we need to do a GC if this is a
625 * multi-threaded program...*/
627 /*if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
628 if (state.DSM&&lb.isAtomic())
629 output.println("checkcollect2(&"+localsprefix+",trans);");
631 output.println("checkcollect(&"+localsprefix+");");
634 /* Create queues to store objects need to be transferred to other cores and their destination*/
635 output.println(" struct Queue * totransobjqueue = createQueue();");
636 output.println(" struct transObjInfo * tmpObjInfo = NULL;");
638 this.m_aliasSets = null;
639 this.m_aliasFNTbl4Para = null;
640 this.m_aliasFNTbl = null;
641 this.m_aliaslocksTbl4FN = null;
642 outputAliasLockCode(fm, lb, output);
644 /* generate print information for RAW version */
645 output.println("#ifdef RAW");
647 output.println("int tmpsum = 0;");
648 output.println("char * taskname = \"" + task.getSymbol() + "\";");
649 output.println("int tmplen = " + task.getSymbol().length() + ";");
650 output.println("int tmpindex = 1;");
651 output.println("for(;tmpindex < tmplen; tmpindex++) {");
652 output.println(" tmpsum = tmpsum * 10 + *(taskname + tmpindex) - '0';");
654 output.println("#ifdef RAWPATH");
655 output.println("raw_test_pass(0xAAAA);");
656 output.println("raw_test_pass_reg(tmpsum);");
657 //output.println("raw_test_pass(raw_get_cycle());");
658 output.println("#endif");
659 output.println("#ifdef RAWDEBUG");
660 output.println("raw_test_pass(0xAAAA);");
661 output.println("raw_test_pass_reg(tmpsum);");
662 output.println("#endif");
664 output.println("#endif");
666 for(int i = 0; i < fm.numParameters(); ++i) {
667 TempDescriptor temp = fm.getParameter(i);
668 output.println(" ++" + super.generateTemp(fm, temp, lb)+"->version;");
671 /* Do the actual code generation */
672 FlatNode current_node=null;
673 HashSet tovisit=new HashSet();
674 HashSet visited=new HashSet();
675 tovisit.add(fm.getNext(0));
676 while(current_node!=null||!tovisit.isEmpty()) {
677 if (current_node==null) {
678 current_node=(FlatNode)tovisit.iterator().next();
679 tovisit.remove(current_node);
681 visited.add(current_node);
682 if (nodetolabel.containsKey(current_node))
683 output.println("L"+nodetolabel.get(current_node)+":");
684 /*if (state.INSTRUCTIONFAILURE) {
685 if (state.THREAD||state.DSM) {
686 output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
689 output.println("if ((--instructioncount)==0) injectinstructionfailure();");
691 if (current_node.numNext()==0) {
693 super.generateFlatNode(fm, lb, current_node, output);
694 if (current_node.kind()!=FKind.FlatReturnNode) {
695 //output.println(" flushAll();");
696 output.println("#ifdef RAWCACHEFLUSH");
697 output.println("raw_user_interrupts_off();");
698 output.println("#ifdef RAWDEBUG");
699 output.println("raw_test_pass(0xec00);");
700 output.println("#endif");
701 output.println("raw_flush_entire_cache();");
702 output.println("#ifdef RAWDEBUG");
703 output.println("raw_test_pass(0xecff);");
704 output.println("#endif");
705 output.println("raw_user_interrupts_on();");
706 output.println("#endif");
707 outputTransCode(output);
708 output.println(" return;");
711 } else if(current_node.numNext()==1) {
713 super.generateFlatNode(fm, lb, current_node, output);
714 FlatNode nextnode=current_node.getNext(0);
715 if (visited.contains(nextnode)) {
716 output.println("goto L"+nodetolabel.get(nextnode)+";");
719 current_node=nextnode;
720 } else if (current_node.numNext()==2) {
723 super.generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
724 if (!visited.contains(current_node.getNext(1)))
725 tovisit.add(current_node.getNext(1));
726 if (visited.contains(current_node.getNext(0))) {
727 output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
730 current_node=current_node.getNext(0);
731 } else throw new Error();
734 output.println("}\n\n");
737 /** This method outputs TaskDescriptor information */
738 private void generateTaskDescriptor(PrintWriter output,
743 int num = this.currentSchedule.getCoreNum();
745 output.println("/* TaskDescriptor information for task " + task.getSymbol() + " on core " + num + "*/");
747 for (int i=0; i<task.numParameters(); i++) {
748 VarDescriptor param_var=task.getParameter(i);
749 TypeDescriptor param_type=task.getParamType(i);
750 FlagExpressionNode param_flag=task.getFlag(param_var);
751 TagExpressionList param_tag=task.getTag(param_var);
754 if (param_flag==null) {
755 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
756 output.println("0x0, 0x0 };");
759 DNFFlag dflag=param_flag.getDNF();
760 dnfterms=dflag.size();
762 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
763 output.println("int parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
764 for(int j=0; j<dflag.size(); j++) {
767 Vector term=dflag.get(j);
770 for(int k=0; k<term.size(); k++) {
771 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
772 FlagDescriptor fd=dfa.getFlag();
773 boolean negated=dfa.getNegated();
774 int flagid=1<<((Integer)flags.get(fd)).intValue();
779 output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
781 output.println("};");
784 output.println("int parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+"[]={");
785 //BUG...added next line to fix, test with any task program
787 for(int j=0; j<param_tag.numTags(); j++) {
790 /* for each tag we need */
791 /* which slot it is */
792 /* what type it is */
793 TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
794 TempDescriptor tmp=param_tag.getTemp(j);
795 int slot=fm.getTagInt(tmp);
796 output.println(slot+", "+state.getTagId(tvd.getTag()));
798 output.println("};");
800 // generate object queue for this parameter
801 String qname = this.objqueueprefix+i+"_"+task.getCoreSafeSymbol(num);
802 if(param_type.getClassDesc().getSymbol().equals("StartupObject")) {
803 this.startupcorenum = num;
805 if(qnames[param_type.getClassDesc().getId()] == null) {
806 qnames[param_type.getClassDesc().getId()] = new Vector();
808 qnames[param_type.getClassDesc().getId()].addElement(qname);
809 outtask.println("extern struct parameterwrapper " + qname + ";");
810 output.println("struct parameterwrapper " + qname + "={");
811 output.println(".objectset = 0,"); // objectset
812 output.println("/* number of DNF terms */ .numberofterms = "+dnfterms+","); // numberofterms
813 output.println(".intarray = parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
816 output.println("/* number of tags */ .numbertags = "+param_tag.numTags()+",");
818 output.println("/* number of tags */ .numbertags = 0,");
819 output.println(".tagarray = parametertag_"+i+"_"+task.getCoreSafeSymbol(num)+","); // tagarray
820 output.println(".task = 0,"); // task
821 output.println(".slot = " + i + ","); // slot
823 output.println("};");
825 output.println("struct parameterdescriptor parameter_"+i+"_"+task.getCoreSafeSymbol(num)+"={");
826 output.println("/* type */"+param_type.getClassDesc().getId()+",");
827 output.println("/* number of DNF terms */"+dnfterms+",");
828 output.println("parameterdnf_"+i+"_"+task.getCoreSafeSymbol(num)+","); // intarray
829 output.println("&" + qname + ","); // queue
830 //BUG, added next line to fix and else statement...test
831 //with any task program
833 output.println("/* number of tags */"+param_tag.numTags()+",");
835 output.println("/* number of tags */ 0,");
836 output.println("parametertag_"+i+"_"+task.getCoreSafeSymbol(num)); // tagarray
837 output.println("};");
840 /* parameter queues for this task*/
841 output.println("struct parameterwrapper * " + this.paramqarrayprefix + task.getCoreSafeSymbol(num)+"[] = {");
842 for (int i=0; i<task.numParameters(); i++) {
845 output.print("&" + this.objqueueprefix + i + "_" + task.getCoreSafeSymbol(num));
847 output.println("};");
849 output.println("struct parameterdescriptor * parameterdescriptors_"+task.getCoreSafeSymbol(num)+"[] = {");
850 for (int i=0; i<task.numParameters(); i++) {
853 output.print("¶meter_"+i+"_"+task.getCoreSafeSymbol(num));
855 output.println("};");
857 output.println("struct taskdescriptor " + this.taskprefix + task.getCoreSafeSymbol(num) + "={");
858 output.println("&"+task.getCoreSafeSymbol(num)+",");
859 output.println("/* number of parameters */" +task.numParameters() + ",");
860 int numtotal=task.numParameters()+fm.numTags();
861 output.println("/* number total parameters */" +numtotal + ",");
862 output.println("parameterdescriptors_"+task.getCoreSafeSymbol(num)+",");
863 output.println("\""+task.getSymbol()+"\"");
864 output.println("};");
869 /** This method generates header information for the task
870 * referenced by the Descriptor des. */
872 private void generateTaskHeader(FlatMethod fm,
875 PrintWriter output) {
877 ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
878 TaskDescriptor task=(TaskDescriptor) des;
880 int num = this.currentSchedule.getCoreNum();
881 //catch the constructor case
882 output.print("void ");
883 output.print(task.getCoreSafeSymbol(num)+"(");
885 boolean printcomma=false;
886 if (GENERATEPRECISEGC) {
887 output.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
891 /*if (state.DSM&&lb.isAtomic()) {
894 output.print("transrecord_t * trans");
898 if (!GENERATEPRECISEGC) {
900 output.println("void * parameterarray[]) {");
901 /* Unpack variables */
902 for(int i=0; i<objectparams.numPrimitives(); i++) {
903 TempDescriptor temp=objectparams.getPrimitive(i);
904 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
906 for(int i=0; i<fm.numTags(); i++) {
907 TempDescriptor temp=fm.getTag(i);
908 int offset=i+objectparams.numPrimitives();
909 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+i+"___=parameterarray["+offset+"];"); // add i to fix bugs of duplicate definition of tags
912 if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
913 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
914 } else output.println(") {");
917 protected void generateFlagOrAnd(FlatFlagActionNode ffan,
924 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
925 output.println("flagorandinit("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
927 int num = this.currentSchedule.getCoreNum();
928 ClassDescriptor cd = temp.getType().getClassDesc();
929 Vector<FlagState> initfstates = ffan.getInitFStates(cd);
930 for(int i = 0; i < initfstates.size(); ++i) {
931 FlagState tmpFState = initfstates.elementAt(i);
933 QueueInfo qinfo = outputqueues(tmpFState, num, output, false);
934 output.println("flagorand("+super.generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+
935 ", 0x"+Integer.toHexString(andmask)+", " + qinfo.qname +
936 ", " + qinfo.length + ");");
939 if(ffan.getTaskType()==FlatFlagActionNode.TASKEXIT) {
940 // generate codes for profiling, recording which task exit it is
941 output.println("#ifdef RAWPROFILE");
942 output.println("setTaskExitIndex(" + ffan.getTaskExitIndex() + ");");
943 output.println("#endif");
948 protected void generateObjectDistribute(FlatFlagActionNode ffan,
952 PrintWriter output) {
953 ClassDescriptor cd = temp.getType().getClassDesc();
954 Vector<FlagState> initfstates = null;
955 Vector[] targetFStates = null;
956 if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
957 targetFStates = new Vector[1];
958 targetFStates[0] = ffan.getTargetFStates4NewObj(cd);
960 initfstates = ffan.getInitFStates(cd);
961 targetFStates = new Vector[initfstates.size()];
962 for(int i = 0; i < initfstates.size(); ++i) {
963 FlagState fs = initfstates.elementAt(i);
964 targetFStates[i] = ffan.getTargetFStates(fs);
966 if(!fs.isSetmask()) {
967 Hashtable flags=(Hashtable)flagorder.get(cd);
970 Iterator it_flags = fs.getFlags();
971 while(it_flags.hasNext()) {
972 FlagDescriptor fd = (FlagDescriptor)it_flags.next();
973 int flagid=1<<((Integer)flags.get(fd)).intValue();
977 fs.setAndmask(andmask);
978 fs.setCheckmask(checkmask);
983 boolean isolate = true; // check if this flagstate can associate to some task with multiple params which can
984 // reside on multiple cores
985 if((this.currentSchedule == null) && (fm.getMethod().getClassDesc().getSymbol().equals("ServerSocket"))) {
986 // ServerSocket object will always reside on current core
987 for(int j = 0; j < targetFStates.length; ++j) {
988 if(initfstates != null) {
989 FlagState fs = initfstates.elementAt(j);
990 output.println("if(" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
991 + ")==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
993 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
994 for(int i = 0; i < tmpfstates.size(); ++i) {
995 FlagState tmpFState = tmpfstates.elementAt(i);
997 // may have bugs here
998 output.println("/* reside on this core*");
999 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1001 if(initfstates != null) {
1002 output.println("}");
1008 int num = this.currentSchedule.getCoreNum();
1009 Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
1010 for(int j = 0; j < targetFStates.length; ++j) {
1011 FlagState fs = null;
1012 if(initfstates != null) {
1013 fs = initfstates.elementAt(j);
1014 output.println("if((" + generateTempFlagName(fm, temp, lb) + "&(0x" + Integer.toHexString(fs.getAndmask())
1015 + "))==(0x" + Integer.toHexString(fs.getCheckmask()) + ")) {");
1017 Vector<FlagState> tmpfstates = (Vector<FlagState>)targetFStates[j];
1018 for(int i = 0; i < tmpfstates.size(); ++i) {
1019 FlagState tmpFState = tmpfstates.elementAt(i);
1021 if(this.currentSchedule.getAllyCoreTable() == null) {
1024 isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
1025 (this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
1028 // indentify this object as a shared object
1029 // isolate flag is initially set as 1, once this flag is set as 0, it is never reset to 1, i.e. once an object
1030 // is shared, it maybe shared all the time afterwards
1031 output.println("if(" + super.generateTemp(fm, temp, lb) + "->isolate == 1) {");
1032 output.println(" " + super.generateTemp(fm, temp, lb) + "->isolate = 0;");
1033 output.println(" " + super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
1034 output.println("}");
1037 Vector<TranObjInfo> sendto = new Vector<TranObjInfo>();
1038 Queue<Integer> queue = null;
1039 if(targetCoreTbl != null) {
1040 queue = targetCoreTbl.get(tmpFState);
1042 if((queue != null) &&
1043 ((queue.size() != 1) ||
1044 ((queue.size() == 1) && (queue.element().intValue() != num)))) {
1045 // this object may be transferred to other cores
1046 String queuename = (String) this.fsate2qnames[num].get(tmpFState);
1047 String queueins = queuename + "ins";
1049 Object[] cores = queue.toArray();
1051 Integer targetcore = (Integer)cores[0];
1052 if(queue.size() > 1) {
1053 index = queueins + ".index";
1055 if(queue.size() > 1) {
1056 output.println("switch(" + queueins + ".index % " + queueins + ".length) {");
1057 for(int k = 0; k < cores.length; ++k) {
1058 output.println("case " + k + ":");
1059 targetcore = (Integer)cores[k];
1060 if(targetcore.intValue() == num) {
1061 output.println("/* reside on this core*/");
1063 output.println("{");
1064 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1065 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1066 ", " + qinfo.length + ");");
1067 output.println("}");
1071 output.println("/* possibly needed by multi-parameter tasks on this core*/");
1072 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1077 // Is it possible to decide the actual queues?
1078 output.println("/* possibly needed by multi-parameter tasks on this core*/");
1079 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1081 output.println("/* transfer to core " + targetcore.toString() + "*/");
1082 output.println("{");
1083 // enqueue this object and its destinations for later process
1084 // all the possible queues
1085 QueueInfo qinfo = null;
1086 TranObjInfo tmpinfo = new TranObjInfo();
1087 tmpinfo.name = super.generateTemp(fm, temp, lb);
1088 tmpinfo.targetcore = targetcore;
1089 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1090 if(targetFS != null) {
1091 tmpinfo.fs = targetFS;
1093 tmpinfo.fs = tmpFState;
1095 if(!contains(sendto, tmpinfo)) {
1096 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1097 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1098 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1099 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1100 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1101 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1102 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1103 sendto.add(tmpinfo);
1105 output.println("}");
1107 output.println("break;");
1109 output.println("}");
1113 // Is it possible to decide the actual queues?
1114 output.println("/* possibly needed by multi-parameter tasks on this core*/");
1115 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1117 output.println("/* transfer to core " + targetcore.toString() + "*/");
1118 output.println("{");
1119 // enqueue this object and its destinations for later process
1120 // all the possible queues
1121 QueueInfo qinfo = null;
1122 TranObjInfo tmpinfo = new TranObjInfo();
1123 tmpinfo.name = super.generateTemp(fm, temp, lb);
1124 tmpinfo.targetcore = targetcore;
1125 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1126 if(targetFS != null) {
1127 tmpinfo.fs = targetFS;
1129 tmpinfo.fs = tmpFState;
1131 if(!contains(sendto, tmpinfo)) {
1132 qinfo = outputtransqueues(tmpinfo.fs, targetcore, output);
1133 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1134 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1135 output.println("tmpObjInfo->targetcore = "+targetcore.toString()+";");
1136 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1137 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1138 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1139 sendto.add(tmpinfo);
1141 output.println("}");
1143 output.println("/* increase index*/");
1144 output.println("++" + queueins + ".index;");
1146 // this object will reside on current core
1147 output.println("/* reside on this core*/");
1149 output.println("{");
1150 QueueInfo qinfo = outputqueues(tmpFState, num, output, true);
1151 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", " + qinfo.qname +
1152 ", " + qinfo.length + ");");
1153 output.println("}");
1157 output.println("enqueueObject("+super.generateTemp(fm, temp, lb)+", NULL, 0);");
1161 // codes for multi-params tasks
1163 // flagstate associated with some multi-params tasks
1164 // need to be send to other cores
1165 Vector<Integer> targetcores = this.currentSchedule.getAllyCores(tmpFState);
1166 output.println("/* send the shared object to possible queues on other cores*/");
1167 for(int k = 0; k < targetcores.size(); ++k) {
1169 // add the information of exactly which queue
1170 //if(!sendto.contains(targetcores.elementAt(i))) {
1171 // previously not sended to this target core
1172 // enqueue this object and its destinations for later process
1173 output.println("{");
1174 // all the possible queues
1175 QueueInfo qinfo = null;
1176 TranObjInfo tmpinfo = new TranObjInfo();
1177 tmpinfo.name = super.generateTemp(fm, temp, lb);
1178 tmpinfo.targetcore = targetcores.elementAt(i);
1179 FlagState targetFS = this.currentSchedule.getTargetFState(tmpFState);
1180 if(targetFS != null) {
1181 tmpinfo.fs = targetFS;
1183 tmpinfo.fs = tmpFState;
1185 if(!contains(sendto, tmpinfo)) {
1186 qinfo = outputtransqueues(tmpinfo.fs, targetcores.elementAt(i), output);
1187 output.println("tmpObjInfo = RUNMALLOC(sizeof(struct transObjInfo));");
1188 output.println("tmpObjInfo->objptr = (void *)" + tmpinfo.name + ";");
1189 output.println("tmpObjInfo->targetcore = "+targetcores.elementAt(i).toString()+";");
1190 output.println("tmpObjInfo->queues = " + qinfo.qname + ";");
1191 output.println("tmpObjInfo->length = " + qinfo.length + ";");
1192 output.println("addNewItem(totransobjqueue, (void*)tmpObjInfo);");
1193 sendto.add(tmpinfo);
1195 output.println("}");
1201 if(initfstates != null) {
1202 output.println("}");
1207 private QueueInfo outputqueues(FlagState tmpFState,
1210 boolean isEnqueue) {
1212 QueueInfo qinfo = new QueueInfo();
1213 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1214 output.println("struct parameterwrapper * " + qinfo.qname + "[] = {");
1215 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1216 Vector<TaskDescriptor> residetasks = this.currentSchedule.getTasks();
1217 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1218 Vector<Integer> indexes = new Vector<Integer>();
1219 boolean comma = false;
1221 while(it_edges.hasNext()) {
1222 FEdge fe = (FEdge)it_edges.next();
1223 TaskDescriptor td = fe.getTask();
1224 int paraindex = fe.getIndex();
1225 if((!isEnqueue) || (isEnqueue && residetasks.contains(td))) {
1226 if((!tasks.contains(td)) ||
1227 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1228 tasks.addElement(td);
1229 indexes.addElement(paraindex);
1231 output.println(",");
1235 output.print("&" + this.objqueueprefix + paraindex + "_" + td.getCoreSafeSymbol(num));
1240 output.println("};");
1244 private QueueInfo outputtransqueues(FlagState tmpFState,
1246 PrintWriter output) {
1248 QueueInfo qinfo = new QueueInfo();
1249 qinfo.qname = "queues_" + tmpFState.getLabel() + "_" + tmpFState.getiuid();
1250 output.println("int " + qinfo.qname + "_clone[] = {");
1251 Iterator it_edges = tmpFState.getEdgeVector().iterator();
1252 Vector<TaskDescriptor> residetasks = this.scheduling.get(targetcore).getTasks();
1253 Vector<TaskDescriptor> tasks = new Vector<TaskDescriptor>();
1254 Vector<Integer> indexes = new Vector<Integer>();
1255 boolean comma = false;
1257 while(it_edges.hasNext()) {
1258 FEdge fe = (FEdge)it_edges.next();
1259 TaskDescriptor td = fe.getTask();
1260 int paraindex = fe.getIndex();
1261 if(residetasks.contains(td)) {
1262 if((!tasks.contains(td)) ||
1263 ((tasks.contains(td)) && (paraindex != indexes.elementAt(tasks.indexOf(td)).intValue()))) {
1264 tasks.addElement(td);
1265 indexes.addElement(paraindex);
1267 output.println(",");
1271 output.print(residetasks.indexOf(td) + ", ");
1272 output.print(paraindex);
1277 output.println("};");
1278 output.println("int * " + qinfo.qname + " = RUNMALLOC(sizeof(int) * " + qinfo.length * 2 + ");");
1279 output.println("memcpy(" + qinfo.qname + ", (int *)" + qinfo.qname + "_clone, sizeof(int) * " + qinfo.length * 2 + ");");
1283 private class QueueInfo {
1285 public String qname;
1288 private String generateTempFlagName(FlatMethod fm,
1290 LocalityBinding lb) {
1291 MethodDescriptor md=fm.getMethod();
1292 TaskDescriptor task=fm.getTask();
1293 TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1295 if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1296 return td.getSafeSymbol() + "_oldflag";
1299 if (objecttemps.isLocalPtr(td)) {
1300 return localsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1303 if (objecttemps.isParamPtr(td)) {
1304 return paramsprefix+"_"+td.getSafeSymbol() + "_oldflag";
1309 protected void outputTransCode(PrintWriter output) {
1310 output.println("while(0 == isEmpty(totransobjqueue)) {");
1311 output.println(" struct transObjInfo * totransobj = (struct transObjInfo *)(getItem(totransobjqueue));");
1312 output.println(" transferObject(totransobj);");
1313 output.println(" RUNFREE(totransobj->queues);");
1314 output.println(" RUNFREE(totransobj);");
1315 output.println("}");
1316 output.println("freeQueue(totransobjqueue);");
1319 protected void outputAliasLockCode(FlatMethod fm,
1321 PrintWriter output) {
1322 if(this.m_oa == null) {
1325 TaskDescriptor td = fm.getTask();
1326 Object[] allocSites = this.m_oa.getFlaggedAllocationSitesReachableFromTask(td).toArray();
1327 Vector<Vector<Integer>> aliasSets = new Vector<Vector<Integer>>();
1328 Vector<Vector<FlatNew>> aliasFNSets = new Vector<Vector<FlatNew>>();
1329 Hashtable<Integer, Vector<FlatNew>> aliasFNTbl4Para = new Hashtable<Integer, Vector<FlatNew>>();
1330 Hashtable<FlatNew, Vector<FlatNew>> aliasFNTbl = new Hashtable<FlatNew, Vector<FlatNew>>();
1331 for( int i = 0; i < fm.numParameters(); ++i ) {
1332 // for the ith parameter check for aliases to all
1333 // higher numbered parameters
1334 aliasSets.add(null);
1335 for( int j = i + 1; j < fm.numParameters(); ++j ) {
1336 if(this.m_oa.createsPotentialAliases(td, i, j)) {
1337 // ith parameter and jth parameter has alias, create lock to protect them
1338 if(aliasSets.elementAt(i) == null) {
1339 aliasSets.setElementAt(new Vector<Integer>(), i);
1341 aliasSets.elementAt(i).add(j);
1345 // for the ith parameter, check for aliases against
1346 // the set of allocation sites reachable from this
1348 aliasFNSets.add(null);
1349 for(int j = 0; j < allocSites.length; j++) {
1350 AllocationSite as = (AllocationSite)allocSites[j];
1351 if( this.m_oa.createsPotentialAliases(td, i, as) ) {
1352 // ith parameter and allocationsite as has alias
1353 if(aliasFNSets.elementAt(i) == null) {
1354 aliasFNSets.setElementAt(new Vector<FlatNew>(), i);
1356 aliasFNSets.elementAt(i).add(as.getFlatNew());
1361 // for each allocation site check for aliases with
1362 // other allocation sites in the context of execution
1364 for( int i = 0; i < allocSites.length; ++i ) {
1365 AllocationSite as1 = (AllocationSite)allocSites[i];
1366 for(int j = i + 1; j < allocSites.length; j++) {
1367 AllocationSite as2 = (AllocationSite)allocSites[j];
1369 if( this.m_oa.createsPotentialAliases(td, as1, as2) ) {
1370 // as1 and as2 has alias
1371 if(!aliasFNTbl.containsKey(as1.getFlatNew())) {
1372 aliasFNTbl.put(as1.getFlatNew(), new Vector<FlatNew>());
1374 if(!aliasFNTbl.get(as1.getFlatNew()).contains(as2.getFlatNew())) {
1375 aliasFNTbl.get(as1.getFlatNew()).add(as2.getFlatNew());
1381 // if FlatNew N1->N2->N3, we group N1, N2, N3 together
1382 Iterator<FlatNew> it = aliasFNTbl.keySet().iterator();
1383 Vector<FlatNew> visited = new Vector<FlatNew>();
1384 while(it.hasNext()) {
1385 FlatNew tmpfn = it.next();
1386 if(visited.contains(tmpfn)) {
1390 Queue<FlatNew> tovisit = new LinkedList<FlatNew>();
1391 Vector<FlatNew> tmpv = aliasFNTbl.get(tmpfn);
1396 for(int j = 0; j < tmpv.size(); j++) {
1397 tovisit.add(tmpv.elementAt(j));
1400 while(!tovisit.isEmpty()) {
1401 FlatNew fn = tovisit.poll();
1403 Vector<FlatNew> tmpset = aliasFNTbl.get(fn);
1404 if(tmpset != null) {
1405 // merge tmpset to the alias set of the ith parameter
1406 for(int j = 0; j < tmpset.size(); j++) {
1407 if(!tmpv.contains(tmpset.elementAt(j))) {
1408 tmpv.add(tmpset.elementAt(j));
1409 tovisit.add(tmpset.elementAt(j));
1412 aliasFNTbl.remove(fn);
1415 it = aliasFNTbl.keySet().iterator();
1418 // check alias between parameters and between parameter-flatnew
1419 for(int i = 0; i < aliasSets.size(); i++) {
1420 Queue<Integer> tovisit = new LinkedList<Integer>();
1421 Vector<Integer> tmpv = aliasSets.elementAt(i);
1426 for(int j = 0; j < tmpv.size(); j++) {
1427 tovisit.add(tmpv.elementAt(j));
1430 while(!tovisit.isEmpty()) {
1431 int index = tovisit.poll().intValue();
1432 Vector<Integer> tmpset = aliasSets.elementAt(index);
1433 if(tmpset != null) {
1434 // merge tmpset to the alias set of the ith parameter
1435 for(int j = 0; j < tmpset.size(); j++) {
1436 if(!tmpv.contains(tmpset.elementAt(j))) {
1437 tmpv.add(tmpset.elementAt(j));
1438 tovisit.add(tmpset.elementAt(j));
1441 aliasSets.setElementAt(null, index);
1444 Vector<FlatNew> tmpFNSet = aliasFNSets.elementAt(index);
1445 if(tmpFNSet != null) {
1446 // merge tmpFNSet to the aliasFNSet of the ith parameter
1447 if(aliasFNSets.elementAt(i) == null) {
1448 aliasFNSets.setElementAt(tmpFNSet, i);
1450 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1451 for(int j = 0; j < tmpFNSet.size(); j++) {
1452 if(!tmpFNv.contains(tmpFNSet.elementAt(j))) {
1453 tmpFNv.add(tmpFNSet.elementAt(j));
1457 aliasFNSets.setElementAt(null, index);
1463 int numparalock = 0;
1464 Vector<Vector<Integer>> tmpaliasSets = new Vector<Vector<Integer>>();
1465 for(int i = 0; i < aliasSets.size(); i++) {
1466 Vector<Integer> tmpv = aliasSets.elementAt(i);
1469 tmpaliasSets.add(tmpv);
1473 Vector<FlatNew> tmpFNv = aliasFNSets.elementAt(i);
1474 if(tmpFNv != null) {
1475 aliasFNTbl4Para.put(i, tmpFNv);
1481 numparalock = numlock;
1484 this.m_aliasSets = tmpaliasSets;
1485 tmpaliasSets.clear();
1486 tmpaliasSets = null;
1487 aliasFNSets.clear();
1489 this.m_aliasFNTbl4Para = aliasFNTbl4Para;
1490 this.m_aliasFNTbl = aliasFNTbl;
1491 numlock += this.m_aliasFNTbl.size();
1495 output.println("int aliaslocks[" + numlock + "];");
1496 output.println("int tmpi = 0;");
1497 // associate locks with parameters
1499 for(int i = 0; i < this.m_aliasSets.size(); i++) {
1500 Vector<Integer> toadd = this.m_aliasSets.elementAt(i);
1502 output.print("int tmplen_" + lockindex + " = 0;");
1503 output.println("void * tmpptrs_" + lockindex + "[] = {");
1504 for(int j = 0; j < toadd.size(); j++) {
1505 int para = toadd.elementAt(j).intValue();
1506 output.print(super.generateTemp(fm, fm.getParameter(para), lb));
1507 if(j < toadd.size() - 1) {
1510 output.println("};");
1513 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", tmplen_" + lockindex + ", lockRedirectTbl);");
1515 for(int j = 0; j < toadd.size(); j++) {
1516 int para = toadd.elementAt(j).intValue();
1517 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + i + "]);");
1519 // check if this lock is also associated with any FlatNew nodes
1520 if(this.m_aliasFNTbl4Para.containsKey(toadd.elementAt(0))) {
1521 if(this.m_aliaslocksTbl4FN == null) {
1522 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1524 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(toadd.elementAt(0));
1525 for(int j = 0; j < tmpv.size(); j++) {
1526 FlatNew fn = tmpv.elementAt(j);
1527 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1528 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1530 this.m_aliaslocksTbl4FN.get(fn).add(i);
1532 this.m_aliasFNTbl4Para.remove(toadd.elementAt(0));
1537 Object[] key = this.m_aliasFNTbl4Para.keySet().toArray();
1538 for(int i = 0; i < key.length; i++) {
1539 int para = ((Integer)key[i]).intValue();
1541 output.println("void * tmpptrs_" + lockindex + "[] = {" + super.generateTemp(fm, fm.getParameter(para), lb) + "};");
1542 output.println("aliaslocks[tmpi++] = getAliasLock(tmpptrs_" + lockindex + ", 1, lockRedirectTbl);");
1544 output.println("addAliasLock(" + super.generateTemp(fm, fm.getParameter(para), lb) + ", aliaslocks[" + lockindex + "]);");
1545 Vector<FlatNew> tmpv = this.m_aliasFNTbl4Para.get(para);
1546 for(int j = 0; j < tmpv.size(); j++) {
1547 FlatNew fn = tmpv.elementAt(j);
1548 if(this.m_aliaslocksTbl4FN == null) {
1549 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1551 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1552 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1554 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1559 // check m_aliasFNTbl for locks associated with FlatNew nodes
1560 Object[] FNkey = this.m_aliasFNTbl.keySet().toArray();
1561 for(int i = 0; i < FNkey.length; i++) {
1562 FlatNew fn = (FlatNew)FNkey[i];
1563 Vector<FlatNew> tmpv = this.m_aliasFNTbl.get(fn);
1565 output.println("aliaslocks[tmpi++] = (int)(RUNMALLOC(sizeof(int)));");
1567 if(this.m_aliaslocksTbl4FN == null) {
1568 this.m_aliaslocksTbl4FN = new Hashtable<FlatNew, Vector<Integer>>();
1570 if(!this.m_aliaslocksTbl4FN.containsKey(fn)) {
1571 this.m_aliaslocksTbl4FN.put(fn, new Vector<Integer>());
1573 this.m_aliaslocksTbl4FN.get(fn).add(lockindex);
1574 for(int j = 0; j < tmpv.size(); j++) {
1575 FlatNew tfn = tmpv.elementAt(j);
1576 if(!this.m_aliaslocksTbl4FN.containsKey(tfn)) {
1577 this.m_aliaslocksTbl4FN.put(tfn, new Vector<Integer>());
1579 this.m_aliaslocksTbl4FN.get(tfn).add(lockindex);
1586 protected void generateFlatReturnNode(FlatMethod fm,
1589 PrintWriter output) {
1590 if (frn.getReturnTemp()!=null) {
1591 if (frn.getReturnTemp().getType().isPtr())
1592 output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1594 output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1596 if(fm.getTask() != null) {
1597 output.println("#ifdef RAWCACHEFLUSH");
1598 output.println("raw_user_interrupts_off();");
1599 output.println("#ifdef RAWDEBUG");
1600 output.println("raw_test_pass(0xec00);");
1601 output.println("#endif");
1602 output.println("raw_flush_entire_cache();");
1603 output.println("#ifdef RAWDEBUG");
1604 output.println("raw_test_pass(0xecff);");
1605 output.println("#endif");
1606 output.println("raw_user_interrupts_on();");
1607 output.println("#endif");
1608 outputTransCode(output);
1610 output.println("return;");
1614 protected void generateFlatNew(FlatMethod fm,
1617 PrintWriter output) {
1618 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1619 && !fn.isGlobal()) {
1620 // Stash pointer in case of GC
1621 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1622 output.println(revertptr + "=trans->revertlist;");
1624 if (fn.getType().isArray()) {
1625 int arrayid = state.getArrayNumber(fn.getType())
1626 + state.numClasses();
1627 if (fn.isGlobal()) {
1628 output.println(super.generateTemp(fm, fn.getDst(), lb)
1629 + "=allocate_newarrayglobal(trans, " + arrayid + ", "
1630 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1631 } else if (GENERATEPRECISEGC) {
1632 output.println(super.generateTemp(fm, fn.getDst(), lb)
1633 + "=allocate_newarray(&" + localsprefix + ", "
1634 + arrayid + ", " + super.generateTemp(fm, fn.getSize(), lb)
1637 output.println(super.generateTemp(fm, fn.getDst(), lb)
1638 + "=allocate_newarray(" + arrayid + ", "
1639 + super.generateTemp(fm, fn.getSize(), lb) + ");");
1642 if (fn.isGlobal()) {
1643 output.println(super.generateTemp(fm, fn.getDst(), lb)
1644 + "=allocate_newglobal(trans, "
1645 + fn.getType().getClassDesc().getId() + ");");
1646 } else if (GENERATEPRECISEGC) {
1647 output.println(super.generateTemp(fm, fn.getDst(), lb)
1648 + "=allocate_new(&" + localsprefix + ", "
1649 + fn.getType().getClassDesc().getId() + ");");
1651 output.println(super.generateTemp(fm, fn.getDst(), lb)
1653 + fn.getType().getClassDesc().getId() + ");");
1656 if (state.DSM && locality.getAtomic(lb).get(fn).intValue() > 0
1657 && !fn.isGlobal()) {
1658 String revertptr = super.generateTemp(fm, reverttable.get(lb), lb);
1659 output.println("trans->revertlist=" + revertptr + ";");
1661 // create alias lock if necessary
1662 if((this.m_aliaslocksTbl4FN != null) && (this.m_aliaslocksTbl4FN.containsKey(fn))) {
1663 Vector<Integer> tmpv = this.m_aliaslocksTbl4FN.get(fn);
1664 for(int i = 0; i < tmpv.size(); i++) {
1665 output.println("addAliasLock(" + super.generateTemp(fm, fn.getDst(), lb) + ", aliaslocks[" + tmpv.elementAt(i).intValue() + "]);");
1668 // generate codes for profiling, recording how many new objects are created
1669 if(!fn.getType().isArray() &&
1670 (fn.getType().getClassDesc() != null)
1671 && (fn.getType().getClassDesc().hasFlags())) {
1672 output.println("#ifdef RAWPROFILE");
1673 output.println("addNewObjInfo(\"" + fn.getType().getClassDesc().getSymbol() + "\");");
1674 output.println("#endif");
1680 public int targetcore;
1681 public FlagState fs;
1684 private boolean contains(Vector<TranObjInfo> sendto,
1686 if(sendto.size() == 0) {
1689 for(int i = 0; i < sendto.size(); i++) {
1690 TranObjInfo tmp = sendto.elementAt(i);
1691 if(!tmp.name.equals(t.name)) {
1694 if(tmp.targetcore != t.targetcore) {
1697 if(tmp.fs != t.fs) {