+ /* Fix field safe symbols due to shadowing */
+ FieldShadow.handleFieldShadow(state);
+
+ /* Build the virtual dispatch tables */
+
+ buildVirtualTables(outvirtual);
+
+ /* Tag the methods that are invoked by static blocks */
+ tagMethodInvokedByStaticBlock();
+
+ /* Output includes */
+ outmethodheader.println("#ifndef METHODHEADERS_H");
+ outmethodheader.println("#define METHODHEADERS_H");
+ outmethodheader.println("#include \"structdefs.h\"");
+ /*if (state.DSM)
+ outmethodheader.println("#include \"dstm.h\"");*/
+
+ /* Output Structures */
+ outputStructs(outstructs);
+
+ outglobaldefs.println("#ifndef __GLOBALDEF_H_");
+ outglobaldefs.println("#define __GLOBALDEF_H_");
+ outglobaldefs.println("");
+ outglobaldefs.println("struct global_defs_t {");
+ outglobaldefs.println(" int size;");
+ outglobaldefs.println(" void * next;");
+ outglobaldefs.println(" struct ArrayObject * classobjs;");
+
+ outglobaldefsprim.println("#ifndef __GLOBALDEFPRIM_H_");
+ outglobaldefsprim.println("#define __GLOBALDEFPRIM_H_");
+ outglobaldefsprim.println("");
+ outglobaldefsprim.println("struct global_defsprim_t {");
+
+ // Output the C class declarations
+ // These could mutually reference each other
+ outclassdefs.println("#ifndef __CLASSDEF_H_");
+ outclassdefs.println("#define __CLASSDEF_H_");
+ outputClassDeclarations(outclassdefs, outglobaldefs, outglobaldefsprim);
+
+ // Output function prototypes and structures for parameters
+ Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
+ int numclasses = this.state.numClasses();
+ while(it.hasNext()) {
+ ClassDescriptor cn=(ClassDescriptor)it.next();
+ generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs, outglobaldefsprim);
+ }
+ outclassdefs.println("#include \"globaldefs.h\"");
+ outclassdefs.println("#include \"globaldefsprim.h\"");
+ outclassdefs.println("#endif");
+ outclassdefs.close();
+ outglobaldefs.println("};");
+ outglobaldefs.println("");
+ outglobaldefs.println("extern struct global_defs_t * global_defs_p;");
+ outglobaldefs.println("#endif");
+ outglobaldefs.flush();
+ outglobaldefs.close();
+
+ outglobaldefsprim.println("};");
+ outglobaldefsprim.println("");
+ outglobaldefsprim.println("extern struct global_defsprim_t * global_defsprim_p;");
+ outglobaldefsprim.println("#endif");
+ outglobaldefsprim.flush();
+ outglobaldefsprim.close();
+
+ if (state.TASK) {
+ /* Map flags to integers */
+ /* The runtime keeps track of flags using these integers */
+ it=state.getClassSymbolTable().getDescriptorsIterator();
+ while(it.hasNext()) {
+ ClassDescriptor cn=(ClassDescriptor)it.next();
+ mapFlags(cn);
+ }
+ /* Generate Tasks */
+ generateTaskStructs(outstructs, outmethodheader);
+
+ /* Outputs generic task structures if this is a task
+ program */
+ outputTaskTypes(outtask);
+ }
+
+ /* Build the actual methods */
+ outputMethods(outmethod);
+
+ if (state.TASK) {
+ Iterator[] taskits = new Iterator[this.coreNum];
+ for(int i = 0; i < taskits.length; ++i) {
+ taskits[i] = null;
+ }
+ int[] numtasks = new int[this.coreNum];
+ int[][] numqueues = new int[this.coreNum][numclasses];
+ /* Output code for tasks */
+ for(int i = 0; i < this.scheduling.size(); ++i) {
+ this.currentSchedule = this.scheduling.elementAt(i);
+ outputTaskCode(outtaskdefs, outmethod, outtask, taskits, numtasks, numqueues);
+ }
+
+ // Output task descriptors
+ boolean comma = false;
+ outtaskdefs.println("struct parameterwrapper ** objectqueues[][NUMCLASSES] = {");
+ boolean needcomma = false;
+ for(int i = 0; i < numqueues.length; ++i) {
+ if(needcomma) {
+ outtaskdefs.println(",");
+ } else {
+ needcomma = true;
+ }
+ outtaskdefs.println("/* object queue array for core " + i + "*/");
+ outtaskdefs.print("{");
+ comma = false;
+ for(int j = 0; j < numclasses; ++j) {
+ if(comma) {
+ outtaskdefs.println(",");
+ } else {
+ comma = true;
+ }
+ outtaskdefs.print(this.objqarrayprefix + j + "_core" + i);
+ }
+ outtaskdefs.print("}");
+ }
+ outtaskdefs.println("};");
+ needcomma = false;
+ outtaskdefs.println("int numqueues[][NUMCLASSES] = {");
+ for(int i = 0; i < numqueues.length; ++i) {
+ if(needcomma) {
+ outtaskdefs.println(",");
+ } else {
+ needcomma = true;
+ }
+ int[] tmparray = numqueues[i];
+ comma = false;
+ outtaskdefs.print("{");
+ for(int j = 0; j < tmparray.length; ++j) {
+ if(comma) {
+ outtaskdefs.print(",");
+ } else {
+ comma = true;
+ }
+ outtaskdefs.print(tmparray[j]);
+ }
+ outtaskdefs.print("}");
+ }
+ outtaskdefs.println("};");
+
+ /* parameter queue arrays for all the tasks*/
+ outtaskdefs.println("struct parameterwrapper *** paramqueues[] = {");
+ needcomma = false;
+ for(int i = 0; i < this.coreNum; ++i) {
+ if(needcomma) {
+ outtaskdefs.println(",");
+ } else {
+ needcomma = true;
+ }
+ outtaskdefs.println("/* parameter queue array for core " + i + "*/");
+ outtaskdefs.print(this.coreqarrayprefix + i);
+ }
+ outtaskdefs.println("};");
+
+ for(int i = 0; i < taskits.length; ++i) {
+ outtaskdefs.println("struct taskdescriptor * " + this.taskarrayprefix + i + "[]={");
+ Iterator taskit = taskits[i];
+ if(taskit != null) {
+ boolean first=true;
+ while(taskit.hasNext()) {
+ TaskDescriptor td=(TaskDescriptor)taskit.next();
+ if (first)
+ first=false;
+ else
+ outtaskdefs.println(",");
+ outtaskdefs.print("&" + this.taskprefix +td.getCoreSafeSymbol(i));
+ }
+ }
+ outtaskdefs.println();
+ outtaskdefs.println("};");
+ }
+ outtaskdefs.println("struct taskdescriptor ** taskarray[]= {");
+ comma = false;
+ for(int i = 0; i < taskits.length; ++i) {
+ if (comma)
+ outtaskdefs.println(",");
+ else
+ comma = true;
+ outtaskdefs.print(this.taskarrayprefix + i);
+ }
+ outtaskdefs.println("};");
+
+ outtaskdefs.print("int numtasks[]= {");
+ comma = false;
+ for(int i = 0; i < taskits.length; ++i) {
+ if (comma)
+ outtaskdefs.print(",");
+ else
+ comma=true;
+ outtaskdefs.print(numtasks[i]);
+ }
+ outtaskdefs.println("};");
+ outtaskdefs.println("int corenum=0;");
+
+ outtaskdefs.close();
+ outtask.println("#endif");
+ outtask.close();
+ /* Record maximum number of task parameters */
+ outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
+ /* Record maximum number of all types, i.e. length of classsize[] */
+ outstructs.println("#define NUMTYPES "+(state.numClasses() + state.numArrays() + state.numInterfaces()));
+ /* Record number of total cores */
+ outstructs.println("#define NUMCORES "+this.tcoreNum);
+ /* Record number of active cores */
+ outstructs.println("#define NUMCORESACTIVE "+this.coreNum); // this.coreNum
+ // can be reset by the scheduling analysis
+ /* Record number of garbage collection cores */
+ outstructs.println("#ifdef MULTICORE_GC");
+ outstructs.println("#define NUMCORES4GC "+this.gcoreNum);
+ outstructs.println("#endif");
+ /* Record number of core containing startup task */
+ outstructs.println("#define STARTUPCORE "+this.startupcorenum);
+ } //else if (state.main!=null) {
+ /* Generate main method */
+ // outputMainMethod(outmethod);
+ //}
+
+ /* Generate information for task with optional parameters */
+ /*if (state.TASK&&state.OPTIONAL){
+ generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
+ outoptionalarrays.close();
+ } */
+
+ /* Output structure definitions for repair tool */
+ /*if (state.structfile!=null) {
+ buildRepairStructs(outrepairstructs);
+ outrepairstructs.close();
+ }*/
+
+ outputInitStaticAndGlobalMethod(outmethod);
+
+ /* Close files */
+ outmethodheader.println("#endif");
+ outmethodheader.close();
+ outmethod.close();
+ outstructs.println("#endif");
+ outstructs.close();
+ }
+
+ private void outputInitStaticAndGlobalMethod(PrintWriter outmethod) {
+ outmethod.println("void initStaticAndGlobal() {");
+ outmethod.println(" int i;");
+
+ if (state.MULTICOREGC) {
+ outmethod.println(" global_defs_p->size="+globaldefscount+";");
+ outmethod.println(" global_defs_p->next=NULL;");
+ outmethod.println(" for(i=0;i<"+globaldefscount+";i++) {");
+ outmethod.println(" ((struct garbagelist *)global_defs_p)->array[i]=NULL;");
+ outmethod.println(" }");
+ }
+
+ outputClassObjects(outmethod);
+ outputStaticBlocks(outmethod);
+
+ outmethod.println("}");
+ }
+
+ /** This function outputs (1) structures that parameters are
+ * passed in (when PRECISE GC is enabled) and (2) function
+ * prototypes for the tasks */
+
+ protected void generateTaskStructs(PrintWriter output,
+ PrintWriter headersout) {
+ /* Cycle through tasks */
+ for(int i = 0; i < this.scheduling.size(); ++i) {
+ Schedule tmpschedule = this.scheduling.elementAt(i);
+ int num = tmpschedule.getCoreNum();
+ Iterator<TaskDescriptor> taskit = tmpschedule.getTasks().iterator();
+
+ while(taskit.hasNext()) {
+ /* Classify parameters */
+ TaskDescriptor task=taskit.next();
+ FlatMethod fm=state.getMethodFlat(task);
+ generateTempStructs(fm);
+
+ ParamsObject objectparams=(ParamsObject) paramstable.get(task);
+ TempObject objecttemps=(TempObject) tempstable.get(task);
+
+ /* Output parameter structure */
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ output.println("struct "+task.getCoreSafeSymbol(num)+"_params {");
+ output.println(" int size;");
+ output.println(" void * next;");
+ for(int j=0; j<objectparams.numPointers(); j++) {
+ TempDescriptor temp=objectparams.getPointer(j);
+ output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
+ }
+
+ output.println("};\n");
+ if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
+ maxtaskparams=objectparams.numPointers()+fm.numTags();
+ }
+ }
+
+ /* Output temp structure */
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ output.println("struct "+task.getCoreSafeSymbol(num)+"_locals {");
+ output.println(" int size;");
+ output.println(" void * next;");
+ for(int j=0; j<objecttemps.numPointers(); j++) {
+ TempDescriptor temp=objecttemps.getPointer(j);
+ if (temp.getType().isNull())
+ output.println(" void * "+temp.getSafeSymbol()+";");
+ else if(temp.getType().isTag())
+ output.println(" struct "+
+ (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
+ else
+ output.println(" struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
+ }
+ output.println("};\n");
+ }
+
+ /* Output task declaration */
+ headersout.print("void " + task.getCoreSafeSymbol(num)+"(");
+
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ headersout.print("struct "+task.getCoreSafeSymbol(num)+"_params * "+paramsprefix);
+ } else
+ headersout.print("void * parameterarray[]");
+ headersout.println(");\n");
+ }
+ }
+
+ }
+
+ /* This method outputs code for each task. */
+
+ protected void outputTaskCode(PrintWriter outtaskdefs,
+ PrintWriter outmethod,
+ PrintWriter outtask,
+ Iterator[] taskits,
+ int[] numtasks,
+ int[][] numqueues) {
+ /* Compile task based program */
+ outtaskdefs.println("#include \"task.h\"");
+ outtaskdefs.println("#include \"methodheaders.h\"");
+
+ /* Output object transfer queues into method.c*/
+ generateObjectTransQueues(outmethod);
+
+ //Vector[] qnames = new Vector[2];
+ int numclasses = numqueues[0].length;
+ Vector qnames[]= new Vector[numclasses];
+ for(int i = 0; i < qnames.length; ++i) {
+ qnames[i] = null;
+ }
+ Iterator<TaskDescriptor> taskit=this.currentSchedule.getTasks().iterator();
+ while(taskit.hasNext()) {
+ TaskDescriptor td=taskit.next();
+ FlatMethod fm=state.getMethodFlat(td);
+ generateTaskMethod(fm, outmethod);
+ generateTaskDescriptor(outtaskdefs, outtask, fm, td, qnames);
+ }
+
+ // generate queuearray for this core
+ int num = this.currentSchedule.getCoreNum();
+ boolean comma = false;
+ for(int i = 0; i < qnames.length; ++i) {
+ outtaskdefs.println("/* object queue array for class " + i + " on core " + num + "*/");
+ outtaskdefs.println("struct parameterwrapper * " + this.objqarrayprefix + i + "_core" + num + "[] = {");
+ comma = false;
+ Vector tmpvector = qnames[i];
+ if(tmpvector != null) {
+ for(int j = 0; j < tmpvector.size(); ++j) {
+ if(comma) {
+ outtaskdefs.println(",");
+ } else {
+ comma = true;
+ }
+ outtaskdefs.print("&" + tmpvector.elementAt(j));
+ }
+ numqueues[num][i] = tmpvector.size();
+ } else {
+ numqueues[num][i] = 0;
+ }
+ outtaskdefs.println("};");
+ }
+
+ /* All the queues for tasks residing on this core*/
+ comma = false;
+ outtaskdefs.println("/* object queue array for tasks on core " + num + "*/");
+ outtaskdefs.println("struct parameterwrapper ** " + this.coreqarrayprefix + num + "[] = {");
+ taskit=this.currentSchedule.getTasks().iterator();
+ while(taskit.hasNext()) {
+ if (comma) {
+ outtaskdefs.println(",");
+ } else {
+ comma = true;
+ }
+ TaskDescriptor td=taskit.next();
+ outtaskdefs.print(this.paramqarrayprefix + td.getCoreSafeSymbol(num));
+ }
+ outtaskdefs.println("};");
+
+ // record the iterator of tasks on this core
+ taskit=this.currentSchedule.getTasks().iterator();
+ taskits[num] = taskit;
+ numtasks[num] = this.currentSchedule.getTasks().size();
+ }
+
+ /** Prints out definitions for generic task structures */
+ protected void outputTaskTypes(PrintWriter outtask) {
+ outtask.println("#ifndef _TASK_H");
+ outtask.println("#define _TASK_H");
+ outtask.println("#include \"ObjectHash.h\"");
+ outtask.println("#include \"structdefs.h\"");
+ outtask.println("#include \"Queue.h\"");
+ outtask.println("#include <string.h>");
+ outtask.println("#include \"runtime_arch.h\"");
+ //outtask.println("#ifdef RAW");
+ //outtask.println("#include <raw.h>");
+ //outtask.println("#endif");
+ outtask.println();
+ outtask.println("struct tagobjectiterator {");
+ outtask.println(" int istag; /* 0 if object iterator, 1 if tag iterator */");
+ outtask.println(" struct ObjectIterator it; /* Object iterator */");
+ outtask.println(" struct ObjectHash * objectset;");
+ outtask.println("#ifdef OPTIONAL");
+ outtask.println(" int failedstate;");
+ outtask.println("#endif");
+ outtask.println(" int slot;");
+ outtask.println(" int tagobjindex; /* Index for tag or object depending on use */");
+ outtask.println(" /*if tag we have an object binding */");
+ outtask.println(" int tagid;");
+ outtask.println(" int tagobjectslot;");
+ outtask.println(" /*if object, we may have one or more tag bindings */");
+ outtask.println(" int numtags;");
+ outtask.println(" int tagbindings[MAXTASKPARAMS-1]; /* list slots */");
+ outtask.println("};");
+ outtask.println();
+ outtask.println("struct parameterwrapper {");
+ outtask.println(" //int type;");
+ outtask.println(" struct ObjectHash * objectset;");
+ outtask.println(" int numberofterms;");
+ outtask.println(" int * intarray;");
+ outtask.println(" int numbertags;");
+ outtask.println(" int * tagarray;");
+ outtask.println(" struct taskdescriptor * task;");
+ outtask.println(" int slot;");
+ outtask.println(" struct tagobjectiterator iterators[MAXTASKPARAMS-1];");
+ outtask.println("};");
+ outtask.println();
+ outtask.println("extern struct parameterwrapper ** objectqueues[][NUMCLASSES];");
+ outtask.println("extern int numqueues[][NUMCLASSES];");
+ outtask.println();
+ outtask.println("struct parameterdescriptor {");
+ outtask.println(" int type;");
+ outtask.println(" int numberterms;");
+ outtask.println(" int *intarray;");
+ outtask.println(" struct parameterwrapper * queue;");
+ outtask.println(" int numbertags;");
+ outtask.println(" int *tagarray;");
+ outtask.println("};");
+ outtask.println();
+ outtask.println("struct taskdescriptor {");
+ outtask.println(" void * taskptr;");
+ outtask.println(" int numParameters;");
+ outtask.println(" int numTotal;");
+ outtask.println(" struct parameterdescriptor **descriptorarray;");
+ outtask.println(" char * name;");
+ outtask.println("};");
+ outtask.println();
+ outtask.println("extern struct taskdescriptor ** taskarray[];");
+ outtask.println("extern int numtasks[];");
+ outtask.println("extern int corenum;"); // define corenum to identify different core
+ outtask.println("extern struct parameterwrapper *** paramqueues[];");
+ outtask.println();
+ }
+
+ protected void generateObjectTransQueues(PrintWriter output) {
+ if(this.fsate2qnames == null) {
+ this.fsate2qnames = new Hashtable[this.coreNum];
+ for(int i = 0; i < this.fsate2qnames.length; ++i) {
+ this.fsate2qnames[i] = null;
+ }
+ }
+ int num = this.currentSchedule.getCoreNum();
+ assert(this.fsate2qnames[num] == null);
+ Hashtable<FlagState, String> flag2qname = new Hashtable<FlagState, String>();
+ this.fsate2qnames[num] = flag2qname;
+ Hashtable<FlagState, Queue<Integer>> targetCoreTbl = this.currentSchedule.getTargetCoreTable();
+ if(targetCoreTbl != null) {
+ Object[] keys = targetCoreTbl.keySet().toArray();
+ output.println();
+ output.println("/* Object transfer queues for core" + num + ".*/");
+ for(int i = 0; i < keys.length; ++i) {
+ FlagState tmpfstate = (FlagState)keys[i];
+ Object[] targetcores = targetCoreTbl.get(tmpfstate).toArray();
+ String queuename = this.otqueueprefix + tmpfstate.getClassDescriptor().getCoreSafeSymbol(num) + tmpfstate.getuid() + "___";
+ String queueins = queuename + "ins";
+ flag2qname.put(tmpfstate, queuename);
+ output.println("struct " + queuename + " {");
+ output.println(" int * cores;");
+ output.println(" int index;");
+ output.println(" int length;");
+ output.println("};");
+ output.print("int " + queuename + "cores[] = {");
+ for(int j = 0; j < targetcores.length; ++j) {
+ if(j > 0) {
+ output.print(", ");
+ }
+ output.print(((Integer)targetcores[j]).intValue());
+ }
+ output.println("};");
+ output.println("struct " + queuename + " " + queueins + "= {");
+ output.println(/*".cores = " + */ queuename + "cores,");
+ output.println(/*".index = " + */ "0,");
+ output.println(/*".length = " +*/ targetcores.length + "};");
+ }
+ }
+ output.println();
+ }
+
+ protected void generateTaskMethod(FlatMethod fm,
+ PrintWriter output) {
+ /*if (State.PRINTFLAT)
+ System.out.println(fm.printMethod());*/
+ TaskDescriptor task=fm.getTask();
+ assert(task != null);
+ int num = this.currentSchedule.getCoreNum();
+
+ //ParamsObject objectparams=(ParamsObject)paramstable.get(task);
+ generateTaskHeader(fm, task,output);
+
+ TempObject objecttemp=(TempObject) tempstable.get(task);
+
+ if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
+ output.print(" struct "+task.getCoreSafeSymbol(num)+"_locals "+localsprefix+"={");
+
+ output.print(objecttemp.numPointers()+",");
+ output.print(paramsprefix);
+ for(int j=0; j<objecttemp.numPointers(); j++)
+ output.print(", NULL");
+ output.println("};");
+ }
+
+ for(int i=0; i<objecttemp.numPrimitives(); i++) {
+ TempDescriptor td=objecttemp.getPrimitive(i);
+ TypeDescriptor type=td.getType();
+ if (type.isNull())
+ output.println(" void * "+td.getSafeSymbol()+";");
+ else if (state.MGC && type.isClass() && type.getClassDesc().isEnum()) {
+ output.println(" int " + td.getSafeSymbol()+";");
+ } else if (type.isClass()||type.isArray())
+ output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
+ else
+ output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
+ }
+
+ for(int i = 0; i < fm.numParameters(); ++i) {
+ TempDescriptor temp = fm.getParameter(i);
+ output.println(" int "+generateTempFlagName(fm, temp)+" = "+generateTemp(fm, temp)+
+ "->flag;");
+ }
+
+ /* Assign labels to FlatNode's if necessary.*/
+
+ Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm, null);
+
+ /* Check to see if we need to do a GC if this is a
+ * multi-threaded program...*/
+ if(this.state.MULTICOREGC) {
+ output.println("GCCHECK("+localsprefixaddr+");");
+ }