X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FIR%2FFlat%2FBuildCode.java;h=8781ff4e3ca832db40545acb02f3d86ce2a20c59;hb=4cb63e913202459da4fe9d01feb7c02f1b98dd6f;hp=6064c7315cc08798b620de00394b59fb8ef2565d;hpb=da446b8ec35c1423f6300ca9f2378ace88d7fcbb;p=IRC.git diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 6064c731..8781ff4e 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -6,7 +6,17 @@ import IR.Tree.TagExpressionList; import IR.*; import java.util.*; import java.io.*; + import Util.Relation; +import Analysis.TaskStateAnalysis.FlagState; +import Analysis.TaskStateAnalysis.FlagComparator; +import Analysis.TaskStateAnalysis.OptionalTaskDescriptor; +import Analysis.TaskStateAnalysis.Predicate; +import Analysis.TaskStateAnalysis.SafetyAnalysis; +import Analysis.TaskStateAnalysis.TaskIndex; +import Analysis.Locality.LocalityAnalysis; +import Analysis.Locality.LocalityBinding; +import Analysis.Prefetch.*; public class BuildCode { State state; @@ -18,24 +28,49 @@ public class BuildCode { int tag=0; String localsprefix="___locals___"; String paramsprefix="___params___"; + String oidstr="___nextobject___"; + String nextobjstr="___nextobject___"; + String localcopystr="___localcopy___"; public static boolean GENERATEPRECISEGC=false; public static String PREFIX=""; public static String arraytype="ArrayObject"; + public static int flagcount = 0; Virtual virtualcalls; TypeUtil typeutil; - private int maxtaskparams=0; + protected int maxtaskparams=0; + private int maxcount=0; ClassDescriptor[] cdarray; TypeDescriptor[] arraytable; + LocalityAnalysis locality; + Hashtable backuptable; + Hashtable reverttable; + SafetyAnalysis sa; + PrefetchAnalysis pa; + + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) { + this(st, temptovar, typeutil, null, sa, pa); + } - public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) { + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa) { + this(st, temptovar, typeutil, locality, null, pa); + } + + public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa) { + this.sa=sa; + this.pa=pa; state=st; this.temptovar=temptovar; - paramstable=new Hashtable(); + paramstable=new Hashtable(); tempstable=new Hashtable(); fieldorder=new Hashtable(); flagorder=new Hashtable(); this.typeutil=typeutil; - virtualcalls=new Virtual(state); + virtualcalls=new Virtual(state,locality); + if (locality!=null) { + this.locality=locality; + this.backuptable=new Hashtable(); + this.reverttable=new Hashtable(); + } } /** The buildCode method outputs C code for all the methods. The Flat @@ -53,31 +88,24 @@ public class BuildCode { PrintWriter outtask=null; PrintWriter outtaskdefs=null; PrintWriter outoptionalarrays=null; + PrintWriter optionalheaders=null; try { - OutputStream str=new FileOutputStream(PREFIX+"structdefs.h"); - outstructs=new java.io.PrintWriter(str, true); - str=new FileOutputStream(PREFIX+"methodheaders.h"); - outmethodheader=new java.io.PrintWriter(str, true); - str=new FileOutputStream(PREFIX+"classdefs.h"); - outclassdefs=new java.io.PrintWriter(str, true); - str=new FileOutputStream(PREFIX+"methods.c"); - outmethod=new java.io.PrintWriter(str, true); - str=new FileOutputStream(PREFIX+"virtualtable.h"); - outvirtual=new java.io.PrintWriter(str, true); + outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true); + outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true); + outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true); + outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true); + outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true); if (state.TASK) { - str=new FileOutputStream(PREFIX+"task.h"); - outtask=new java.io.PrintWriter(str, true); - str=new FileOutputStream(PREFIX+"taskdefs.c"); - outtaskdefs=new java.io.PrintWriter(str, true); + outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true); + outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true); if (state.OPTIONAL){ - str=new FileOutputStream(PREFIX+"optionnalarrays.c"); - outoptionalarrays=new java.io.PrintWriter(str, true); + outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true); + optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true); } } if (state.structfile!=null) { - str=new FileOutputStream(PREFIX+state.structfile+".struct"); - outrepairstructs=new java.io.PrintWriter(str, true); + outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true); } } catch (Exception e) { e.printStackTrace(); @@ -87,112 +115,31 @@ public class BuildCode { /* Build the virtual dispatch tables */ buildVirtualTables(outvirtual); - /* 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\""); - outstructs.println("#ifndef STRUCTDEFS_H"); - outstructs.println("#define STRUCTDEFS_H"); - outstructs.println("#include \"classdefs.h\""); - - - - /* Output types for short array and string */ - outstructs.println("#define STRINGARRAYTYPE "+ - (state.getArrayNumber( - (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses())); - - outstructs.println("#define OBJECTARRAYTYPE "+ - (state.getArrayNumber( - (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses())); - + /* Output Structures */ + outputStructs(outstructs); - outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId()); - outstructs.println("#define CHARARRAYTYPE "+ - (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses())); - - outstructs.println("#define BYTEARRAYTYPE "+ - (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses())); - - outstructs.println("#define BYTEARRAYARRAYTYPE "+ - (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses())); - - outstructs.println("#define NUMCLASSES "+state.numClasses()); - if (state.TASK) { - outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId()); - outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId()); - outstructs.println("#define TAGARRAYTYPE "+ - (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses())); - } - // Output the C class declarations // These could mutually reference each other - if (state.THREAD) - outclassdefs.println("#include "); - - outclassdefs.println("struct "+arraytype+";"); - - Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); - while(it.hasNext()) { - ClassDescriptor cn=(ClassDescriptor)it.next(); - outclassdefs.println("struct "+cn.getSafeSymbol()+";"); - } - outclassdefs.println(""); - { - //Print out definition for array type - outclassdefs.println("struct "+arraytype+" {"); - outclassdefs.println(" int type;"); - if (state.THREAD) { - outclassdefs.println(" pthread_t tid;"); - outclassdefs.println(" void * lockentry;"); - outclassdefs.println(" int lockcount;"); - } - - if (state.TASK) { - outclassdefs.println(" int flag;"); - outclassdefs.println(" void * flagptr;"); - outclassdefs.println(" int failedstatus;"); - outclassdefs.println(" int * flagset;"); - } - printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs); - outclassdefs.println(" int ___length___;"); - outclassdefs.println("};\n"); - - if (state.TASK) { - //Print out definitions for task types - outtask.println("struct parameterdescriptor {"); - outtask.println("int type;"); - outtask.println("int numberterms;"); - outtask.println("int *intarray;"); - outtask.println("void * queue;"); - outtask.println("int numbertags;"); - outtask.println("int *tagarray;"); - 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("extern struct taskdescriptor * taskarray[];"); - outtask.println("extern numtasks;"); - } - } + outputClassDeclarations(outclassdefs); // Output function prototypes and structures for parameters - it=state.getClassSymbolTable().getDescriptorsIterator(); + Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); while(it.hasNext()) { ClassDescriptor cn=(ClassDescriptor)it.next(); generateCallStructs(cn, outclassdefs, outstructs, outmethodheader); } + outclassdefs.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(); @@ -200,30 +147,193 @@ public class BuildCode { } /* Generate Tasks */ generateTaskStructs(outstructs, outmethodheader); + + /* Outputs generic task structures if this is a task + program */ + outputTaskTypes(outtask); } - outmethodheader.println("#endif"); + /* Build the actual methods */ + outputMethods(outmethod); + + if (state.TASK) { + /* Output code for tasks */ + outputTaskCode(outtaskdefs, outmethod); + outtaskdefs.close(); + /* Record maximum number of task parameters */ + outstructs.println("#define MAXTASKPARAMS "+maxtaskparams); + } 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(); + } + + /* Close files */ + outmethodheader.println("#endif"); outmethodheader.close(); + outmethod.close(); + outstructs.println("#endif"); + outstructs.close(); + } - /* Build the actual methods */ + /* This code just generates the main C method for java programs. + * The main C method packs up the arguments into a string array + * and passes it to the java main method. */ + + private void outputMainMethod(PrintWriter outmethod) { + outmethod.println("int main(int argc, const char *argv[]) {"); + outmethod.println(" int i;"); + outmethod.println("#ifdef TRANSSTATS \n"); + outmethod.println("handle();\n"); + outmethod.println("#endif\n"); + if (state.THREAD||state.DSM) { + outmethod.println("initializethreads();"); + } + if (state.DSM) { + outmethod.println("if (dstmStartup(argv[1])) {"); + if (GENERATEPRECISEGC) { + outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-2);"); + } else { + outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-2);"); + } + } else { + if (GENERATEPRECISEGC) { + outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);"); + } else { + outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);"); + } + } + if (state.DSM) { + outmethod.println(" for(i=2;i___length___)+sizeof(int)))[i-2]=newstring;"); + else + outmethod.println(" ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;"); + outmethod.println(" }"); + + + MethodDescriptor md=typeutil.getMain(); + ClassDescriptor cd=typeutil.getMainClass(); + + outmethod.println(" {"); + if (GENERATEPRECISEGC) { + if (state.DSM) { + outmethod.print(" struct "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + } else + outmethod.print(" struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + outmethod.println("1, NULL,"+"stringarray};"); + if (state.DSM) + outmethod.println(" "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);"); + else + outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);"); + } else { + if (state.DSM) + outmethod.println(" "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);"); + else + outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);"); + } + outmethod.println(" }"); + + if (state.DSM) { + outmethod.println("}"); + } + + if (state.THREAD||state.DSM) { + outmethod.println("pthread_mutex_lock(&gclistlock);"); + outmethod.println("threadcount--;"); + outmethod.println("pthread_cond_signal(&gccond);"); + outmethod.println("pthread_mutex_unlock(&gclistlock);"); + if (state.THREAD) + outmethod.println("pthread_exit(NULL);"); + } + + outmethod.println("#ifdef TRANSSTATS \n"); + outmethod.println("printf(\"****** Transaction Stats ******\\n\");"); + outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);"); + outmethod.println("printf(\"numTransCommit= %d\\n\", numTransCommit);"); + outmethod.println("printf(\"nchashSearch= %d\\n\", nchashSearch);"); + outmethod.println("printf(\"nmhashSearch= %d\\n\", nmhashSearch);"); + outmethod.println("printf(\"nprehashSearch= %d\\n\", nprehashSearch);"); + outmethod.println("printf(\"nRemoteReadSend= %d\\n\", nRemoteSend);"); + outmethod.println("#endif\n"); + outmethod.println("}"); + + } + + /* This method outputs code for each task. */ + + private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) { + /* Compile task based program */ + outtaskdefs.println("#include \"task.h\""); + outtaskdefs.println("#include \"methodheaders.h\""); + Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator(); + while(taskit.hasNext()) { + TaskDescriptor td=(TaskDescriptor)taskit.next(); + FlatMethod fm=state.getMethodFlat(td); + generateFlatMethod(fm, null, outmethod); + generateTaskDescriptor(outtaskdefs, fm, td); + } + + //Output task descriptors + taskit=state.getTaskSymbolTable().getDescriptorsIterator(); + outtaskdefs.println("struct taskdescriptor * taskarray[]= {"); + boolean first=true; + while(taskit.hasNext()) { + TaskDescriptor td=(TaskDescriptor)taskit.next(); + if (first) + first=false; + else + outtaskdefs.println(","); + outtaskdefs.print("&task_"+td.getSafeSymbol()); + } + outtaskdefs.println("};"); + + outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";"); + } + + /* This method outputs most of the methods.c file. This includes + * some standard includes and then an array with the sizes of + * objets and array that stores supertype and then the code for + * the Java methods.. */ + + protected void outputMethods(PrintWriter outmethod) { outmethod.println("#include \"methodheaders.h\""); outmethod.println("#include \"virtualtable.h\""); - outmethod.println("#include "); - if (state.THREAD) + outmethod.println("#include \"runtime.h\""); + if (state.DSM) { + outmethod.println("#include \"addPrefetchEnhance.h\""); + outmethod.println("#include \"localobjects.h\""); + } + if(state.MULTICORE) { + outmethod.println("#include \"task.h\""); + } + if (state.THREAD||state.DSM) outmethod.println("#include "); if (state.main!=null) { outmethod.println("#include "); } - if (state.CONSCHECK) { outmethod.println("#include \"checkers.h\""); } - outclassdefs.println("extern int classsize[];"); - outclassdefs.println("extern int hasflags[];"); - outclassdefs.println("extern int * pointerarray[];"); - outclassdefs.println("extern int supertypes[];"); - //Store the sizes of classes & array elements generateSizeArray(outmethod); @@ -234,113 +344,145 @@ public class BuildCode { generateLayoutStructs(outmethod); /* Generate code for methods */ - Iterator classit=state.getClassSymbolTable().getDescriptorsIterator(); - while(classit.hasNext()) { - ClassDescriptor cn=(ClassDescriptor)classit.next(); - Iterator methodit=cn.getMethods(); - while(methodit.hasNext()) { - /* Classify parameters */ - MethodDescriptor md=(MethodDescriptor)methodit.next(); - FlatMethod fm=state.getMethodFlat(md); - if (!md.getModifiers().isNative()) - generateFlatMethod(fm,outmethod); + if (state.DSM) { + for(Iterator lbit=locality.getLocalityBindings().iterator();lbit.hasNext();) { + LocalityBinding lb=lbit.next(); + MethodDescriptor md=lb.getMethod(); + FlatMethod fm=state.getMethodFlat(md); + if (!md.getModifiers().isNative()) { + generateFlatMethod(fm, lb, outmethod); + } } - } - - if (state.TASK) { - /* Compile task based program */ - outtaskdefs.println("#include \"task.h\""); - outtaskdefs.println("#include \"methodheaders.h\""); - Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator(); - while(taskit.hasNext()) { - TaskDescriptor td=(TaskDescriptor)taskit.next(); - FlatMethod fm=state.getMethodFlat(td); - generateFlatMethod(fm, outmethod); - generateTaskDescriptor(outtaskdefs, fm, td); - } - - { - //Output task descriptors - taskit=state.getTaskSymbolTable().getDescriptorsIterator(); - outtaskdefs.println("struct taskdescriptor * taskarray[]= {"); - boolean first=true; - while(taskit.hasNext()) { - TaskDescriptor td=(TaskDescriptor)taskit.next(); - if (first) - first=false; - else - outtaskdefs.println(","); - outtaskdefs.print("&task_"+td.getSafeSymbol()); + } else { + Iterator classit=state.getClassSymbolTable().getDescriptorsIterator(); + while(classit.hasNext()) { + ClassDescriptor cn=(ClassDescriptor)classit.next(); + Iterator methodit=cn.getMethods(); + while(methodit.hasNext()) { + /* Classify parameters */ + MethodDescriptor md=(MethodDescriptor)methodit.next(); + FlatMethod fm=state.getMethodFlat(md); + if (!md.getModifiers().isNative()) { + generateFlatMethod(fm, null, outmethod); + } } - outtaskdefs.println("};"); } + } + } - outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";"); + protected void outputStructs(PrintWriter outstructs) { + outstructs.println("#ifndef STRUCTDEFS_H"); + outstructs.println("#define STRUCTDEFS_H"); + outstructs.println("#include \"classdefs.h\""); - } else if (state.main!=null) { - /* Generate main method */ - outmethod.println("int main(int argc, const char *argv[]) {"); - outmethod.println(" int i;"); - if (GENERATEPRECISEGC) { - outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);"); - } else { - outmethod.println(" struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);"); - } - if (state.THREAD) { - outmethod.println("initializethreads();"); - } - outmethod.println(" for(i=1;i___length___)+sizeof(int)))[i-1]=newstring;"); - outmethod.println(" }"); + /* Output #defines that the runtime uses to determine type + * numbers for various objects it needs */ + outstructs.println("#define MAXCOUNT "+maxcount); + if (state.DSM) { + LocalityBinding lb=new LocalityBinding(typeutil.getRun(), false); + lb.setGlobalThis(LocalityAnalysis.GLOBAL); + outstructs.println("#define RUNMETHOD "+virtualcalls.getLocalityNumber(lb)); + } + + outstructs.println("#define STRINGARRAYTYPE "+ + (state.getArrayNumber( + (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses())); + outstructs.println("#define OBJECTARRAYTYPE "+ + (state.getArrayNumber( + (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses())); - MethodDescriptor md=typeutil.getMain(); - ClassDescriptor cd=typeutil.getMainClass(); - outmethod.println(" {"); - if (GENERATEPRECISEGC) { - outmethod.print(" struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); - outmethod.println("1, NULL,"+"stringarray};"); - outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);"); - } else - outmethod.println(" "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);"); - outmethod.println(" }"); - - if (state.THREAD) { - outmethod.println("pthread_mutex_lock(&gclistlock);"); - outmethod.println("threadcount--;"); - outmethod.println("pthread_cond_signal(&gccond);"); - outmethod.println("pthread_mutex_unlock(&gclistlock);"); - outmethod.println("pthread_exit(NULL);"); - } - outmethod.println("}"); - } - if (state.TASK) - outstructs.println("#define MAXTASKPARAMS "+maxtaskparams); + outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId()); + outstructs.println("#define CHARARRAYTYPE "+ + (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses())); + outstructs.println("#define BYTEARRAYTYPE "+ + (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses())); - /* Output structure definitions for repair tool */ - if (state.structfile!=null) { - buildRepairStructs(outrepairstructs); - outrepairstructs.close(); + outstructs.println("#define BYTEARRAYARRAYTYPE "+ + (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses())); + + outstructs.println("#define NUMCLASSES "+state.numClasses()); + if (state.TASK) { + outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId()); + outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId()); + outstructs.println("#define TAGARRAYTYPE "+ + (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses())); } - outstructs.println("#endif"); - - outstructs.close(); - outmethod.close(); + } - generateOptionalArrays(outoptionalarrays); - outoptionalarrays.close(); + protected void outputClassDeclarations(PrintWriter outclassdefs) { + if (state.THREAD||state.DSM) + outclassdefs.println("#include "); + if(state.OPTIONAL) + outclassdefs.println("#include \"optionalstruct.h\""); + outclassdefs.println("struct "+arraytype+";"); + /* Start by declaring all structs */ + Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); + while(it.hasNext()) { + ClassDescriptor cn=(ClassDescriptor)it.next(); + outclassdefs.println("struct "+cn.getSafeSymbol()+";"); + } + outclassdefs.println(""); + //Print out definition for array type + outclassdefs.println("struct "+arraytype+" {"); + outclassdefs.println(" int type;"); + if (state.THREAD) { + outclassdefs.println(" pthread_t tid;"); + outclassdefs.println(" void * lockentry;"); + outclassdefs.println(" int lockcount;"); + } + if (state.TASK) { + outclassdefs.println(" int flag;"); + if(!state.MULTICORE) { + outclassdefs.println(" void * flagptr;"); + } else { + outclassdefs.println(" int isolate;"); // indicate if this object is shared or not + outclassdefs.println(" int version;"); + outclassdefs.println(" struct ___Object___ * original;"); + } + if(state.OPTIONAL){ + outclassdefs.println(" int numfses;"); + outclassdefs.println(" int * fses;"); + } + } + printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs); + + outclassdefs.println(" int ___length___;"); + outclassdefs.println("};\n"); + outclassdefs.println("extern int classsize[];"); + outclassdefs.println("extern int hasflags[];"); + outclassdefs.println("extern unsigned int * pointerarray[];"); + outclassdefs.println("extern int supertypes[];"); + } + /** Prints out definitions for generic task structures */ + + private void outputTaskTypes(PrintWriter outtask) { + outtask.println("#ifndef _TASK_H"); + outtask.println("#define _TASK_H"); + outtask.println("struct parameterdescriptor {"); + outtask.println("int type;"); + outtask.println("int numberterms;"); + outtask.println("int *intarray;"); + outtask.println("void * queue;"); + outtask.println("int numbertags;"); + outtask.println("int *tagarray;"); + 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("extern struct taskdescriptor * taskarray[];"); + outtask.println("extern numtasks;"); + outtask.println("#endif"); } - private int maxcount=0; private void buildRepairStructs(PrintWriter outrepairstructs) { Iterator classit=state.getClassSymbolTable().getDescriptorsIterator(); @@ -350,7 +492,9 @@ public class BuildCode { outrepairstructs.println(" int __type__;"); if (state.TASK) { outrepairstructs.println(" int __flag__;"); - outrepairstructs.println(" int __flagptr__;"); + if(!state.MULTICORE) { + outrepairstructs.println(" int __flagptr__;"); + } } printRepairStruct(cn, outrepairstructs); outrepairstructs.println("}\n"); @@ -372,7 +516,6 @@ public class BuildCode { */ outrepairstructs.println("}\n"); } - } private void printRepairStruct(ClassDescriptor cn, PrintWriter output) { @@ -396,7 +539,7 @@ public class BuildCode { } /** This method outputs TaskDescriptor information */ - void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) { + private void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) { for (int i=0;imaxcount) maxcount=virtualcalls.getMethodCount(cd); } - MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount]; + MethodDescriptor[][] virtualtable=null; + LocalityBinding[][] lbvirtualtable=null; + if (state.DSM) + lbvirtualtable=new LocalityBinding[state.numClasses()+state.numArrays()][maxcount]; + else + virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount]; /* Fill in virtual table */ classit=state.getClassSymbolTable().getDescriptorsIterator(); while(classit.hasNext()) { ClassDescriptor cd=(ClassDescriptor)classit.next(); - fillinRow(cd, virtualtable, cd.getId()); + if (state.DSM) + fillinRow(cd, lbvirtualtable, cd.getId()); + else + fillinRow(cd, virtualtable, cd.getId()); } ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass); @@ -510,7 +660,10 @@ public class BuildCode { while(arrayit.hasNext()) { TypeDescriptor td=(TypeDescriptor)arrayit.next(); int id=state.getArrayNumber(td); - fillinRow(objectcd, virtualtable, id+state.numClasses()); + if (state.DSM) + fillinRow(objectcd, lbvirtualtable, id+state.numClasses()); + else + fillinRow(objectcd, virtualtable, id+state.numClasses()); } outvirtual.print("void * virtualtable[]={"); @@ -519,7 +672,11 @@ public class BuildCode { for(int j=0;j lbit=locality.getClassBindings(cd).iterator();lbit.hasNext();) { + LocalityBinding lb=lbit.next(); + MethodDescriptor md=lb.getMethod(); + //Is the method static or a constructor + if (md.isStatic()||md.getReturnType()==null) + continue; + int methodnum=virtualcalls.getLocalityNumber(lb); + virtualtable[rownum][methodnum]=lb; + } + } + + /** Generate array that contains the sizes of class objects. The * object allocation functions in the runtime use this * information. */ private void generateSizeArray(PrintWriter outclassdefs) { - outclassdefs.print("int classsize[]={"); + outclassdefs.print("extern struct prefetchCountStats * evalPrefetch;\n"); + outclassdefs.print("#ifdef TRANSSTATS \n"); + outclassdefs.print("extern int numTransAbort;\n"); + outclassdefs.print("extern int numTransCommit;\n"); + outclassdefs.print("extern int nchashSearch;\n"); + outclassdefs.print("extern int nmhashSearch;\n"); + outclassdefs.print("extern int nprehashSearch;\n"); + outclassdefs.print("extern int nRemoteSend;\n"); + outclassdefs.print("extern void handle();\n"); + outclassdefs.print("#endif\n"); + outclassdefs.print("int numprefetchsites = " + pa.prefetchsiteid + ";\n"); + + outclassdefs.print("int classsize[]={"); Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); cdarray=new ClassDescriptor[state.numClasses()]; while(it.hasNext()) { @@ -594,12 +781,15 @@ public class BuildCode { * These objects tell the compiler which temps need to be * allocated. */ - private void generateTempStructs(FlatMethod fm) { + protected void generateTempStructs(FlatMethod fm, LocalityBinding lb) { MethodDescriptor md=fm.getMethod(); TaskDescriptor task=fm.getTask(); - + Set saveset=lb!=null?locality.getTempSet(lb):null; ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++); - if (md!=null) + + if (lb!=null) + paramstable.put(lb, objectparams); + else if (md!=null) paramstable.put(md, objectparams); else paramstable.put(task, objectparams); @@ -607,10 +797,13 @@ public class BuildCode { for(int i=0;i tmpit=backuptable.values().iterator();tmpit.hasNext();) { + TempDescriptor tmp=tmpit.next(); + TypeDescriptor type=tmp.getType(); + if (type.isPtr()&&GENERATEPRECISEGC) + objecttemps.addPtr(tmp); + else + objecttemps.addPrim(tmp); + } + /* Create temp to hold revert table */ + if (lb.getHasAtomic()||lb.isAtomic()) { + TempDescriptor reverttmp=new TempDescriptor("revertlist", typeutil.getClass(TypeUtil.ObjectClass)); + if (GENERATEPRECISEGC) + objecttemps.addPtr(reverttmp); + else + objecttemps.addPrim(reverttmp); + reverttable.put(lb, reverttmp); } } } - + + /** This method outputs the following information about classes + * and arrays: + * (1) For classes, what are the locations of pointers. + * (2) For arrays, does the array contain pointers or primitives. + * (3) For classes, does the class contain flags. + */ + private void generateLayoutStructs(PrintWriter output) { Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); while(it.hasNext()) { ClassDescriptor cn=(ClassDescriptor)it.next(); - output.println("int "+cn.getSafeSymbol()+"_pointers[]={"); + output.println("unsigned int "+cn.getSafeSymbol()+"_pointers[]={"); Iterator allit=cn.getFieldTable().getAllDescriptorsIterator(); int count=0; while(allit.hasNext()) { FieldDescriptor fd=(FieldDescriptor)allit.next(); TypeDescriptor type=fd.getType(); - if (type.isPtr()||type.isArray()) + if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now + continue; + if (type.isPtr()) count++; } output.print(count); @@ -659,14 +887,16 @@ public class BuildCode { while(allit.hasNext()) { FieldDescriptor fd=(FieldDescriptor)allit.next(); TypeDescriptor type=fd.getType(); - if (type.isPtr()||type.isArray()) { + if (state.DSM&&fd.isGlobal()) //Don't GC the global objects for now + continue; + if (type.isPtr()) { output.println(","); - output.print("((int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))"); + output.print("((unsigned int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))"); } } output.println("};"); } - output.println("int * pointerarray[]={"); + output.println("unsigned int * pointerarray[]={"); boolean needcomma=false; for(int i=0;i nativemethods=new HashSet(); + Set lbset=locality.getClassBindings(cn); + if (lbset!=null) { + for(Iterator lbit=lbset.iterator();lbit.hasNext();) { + LocalityBinding lb=lbit.next(); + MethodDescriptor md=lb.getMethod(); + if (md.getModifiers().isNative()) { + //make sure we only print a native method once + if (nativemethods.contains(md)) { + FlatMethod fm=state.getMethodFlat(md); + generateTempStructs(fm, lb); + continue; + } else + nativemethods.add(md); + } + generateMethod(cn, md, lb, headersout, output); + } + } + for(Iterator methodit=cn.getMethods();methodit.hasNext();) { + MethodDescriptor md=(MethodDescriptor)methodit.next(); + if (md.getModifiers().isNative()&&!nativemethods.contains(md)) { + //Need to build param structure for library code + FlatMethod fm=state.getMethodFlat(md); + generateTempStructs(fm, null); + generateMethodParam(cn, md, null, output); + } + } - ParamsObject objectparams=(ParamsObject) paramstable.get(md); - TempObject objecttemps=(TempObject) tempstable.get(md); + } else + for(Iterator methodit=cn.getMethods();methodit.hasNext();) { + MethodDescriptor md=(MethodDescriptor)methodit.next(); + generateMethod(cn, md, null, headersout, output); + } + } - /* Output parameter structure */ - if (GENERATEPRECISEGC) { + private void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter output) { + /* Output parameter structure */ + if (GENERATEPRECISEGC) { + ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null?lb:md); + if (state.DSM&&lb!=null) + output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {"); + else output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {"); - output.println(" int size;"); - output.println(" void * next;"); - for(int i=0;i0) { - //1) Edge >1 of node - nodetolabel.put(nn,new Integer(labelindex++)); - } - if (!visited.contains(nn)&&!tovisit.contains(nn)) { - tovisit.add(nn); - } else { - //2) Join point - nodetolabel.put(nn,new Integer(labelindex++)); - } - } - } + Hashtable nodetolabel=assignLabels(fm); + + /* Check to see if we need to do a GC if this is a + * multi-threaded program...*/ - if (state.THREAD&&GENERATEPRECISEGC) { - output.println("checkcollect(&"+localsprefix+");"); + if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) { + if (state.DSM&&lb.isAtomic()) + output.println("checkcollect2(&"+localsprefix+",trans);"); + else + output.println("checkcollect(&"+localsprefix+");"); } - //Do the actual code generation - tovisit=new HashSet(); - visited=new HashSet(); + /* Do the actual code generation */ + FlatNode current_node=null; + HashSet tovisit=new HashSet(); + HashSet visited=new HashSet(); tovisit.add(fm.getNext(0)); while(current_node!=null||!tovisit.isEmpty()) { if (current_node==null) { @@ -1026,7 +1317,7 @@ public class BuildCode { if (nodetolabel.containsKey(current_node)) output.println("L"+nodetolabel.get(current_node)+":"); if (state.INSTRUCTIONFAILURE) { - if (state.THREAD) { + if (state.THREAD||state.DSM) { output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}"); } else @@ -1034,14 +1325,14 @@ public class BuildCode { } if (current_node.numNext()==0) { output.print(" "); - generateFlatNode(fm, current_node, output); + generateFlatNode(fm, lb, current_node, output); if (current_node.kind()!=FKind.FlatReturnNode) { output.println(" return;"); } current_node=null; } else if(current_node.numNext()==1) { output.print(" "); - generateFlatNode(fm, current_node, output); + generateFlatNode(fm, lb, current_node, output); FlatNode nextnode=current_node.getNext(0); if (visited.contains(nextnode)) { output.println("goto L"+nodetolabel.get(nextnode)+";"); @@ -1051,7 +1342,7 @@ public class BuildCode { } else if (current_node.numNext()==2) { /* Branch */ output.print(" "); - generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output); + generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output); if (!visited.contains(current_node.getNext(1))) tovisit.add(current_node.getNext(1)); if (visited.contains(current_node.getNext(0))) { @@ -1061,16 +1352,48 @@ public class BuildCode { current_node=current_node.getNext(0); } else throw new Error(); } + output.println("}\n\n"); + } + /** This method assigns labels to FlatNodes */ - output.println("}\n\n"); + protected Hashtable assignLabels(FlatMethod fm) { + HashSet tovisit=new HashSet(); + HashSet visited=new HashSet(); + int labelindex=0; + Hashtable nodetolabel=new Hashtable(); + tovisit.add(fm.getNext(0)); + + /*Assign labels first. A node needs a label if the previous + * node has two exits or this node is a join point. */ + + while(!tovisit.isEmpty()) { + FlatNode fn=(FlatNode)tovisit.iterator().next(); + tovisit.remove(fn); + visited.add(fn); + for(int i=0;i0) { + //1) Edge >1 of node + nodetolabel.put(nn,new Integer(labelindex++)); + } + if (!visited.contains(nn)&&!tovisit.contains(nn)) { + tovisit.add(nn); + } else { + //2) Join point + nodetolabel.put(nn,new Integer(labelindex++)); + } + } + } + return nodetolabel; } - /** Generate text string that corresponds to the Temp td. */ - private String generateTemp(FlatMethod fm, TempDescriptor td) { + + /** Generate text string that corresponds to the TempDescriptor td. */ + protected String generateTemp(FlatMethod fm, TempDescriptor td, LocalityBinding lb) { MethodDescriptor md=fm.getMethod(); TaskDescriptor task=fm.getTask(); - TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task); + TempObject objecttemps=(TempObject) tempstable.get(lb!=null?lb:md!=null?md:task); if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) { return td.getSafeSymbol(); @@ -1086,63 +1409,311 @@ public class BuildCode { throw new Error(); } - private void generateFlatNode(FlatMethod fm, FlatNode fn, PrintWriter output) { + protected void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) { switch(fn.kind()) { + case FKind.FlatAtomicEnterNode: + generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output); + return; + case FKind.FlatAtomicExitNode: + generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output); + return; + case FKind.FlatGlobalConvNode: + generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output); + return; case FKind.FlatTagDeclaration: - generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output); + generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output); return; case FKind.FlatCall: - generateFlatCall(fm, (FlatCall) fn,output); + generateFlatCall(fm, lb, (FlatCall) fn,output); return; case FKind.FlatFieldNode: - generateFlatFieldNode(fm, (FlatFieldNode) fn,output); + generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output); return; case FKind.FlatElementNode: - generateFlatElementNode(fm, (FlatElementNode) fn,output); + generateFlatElementNode(fm, lb, (FlatElementNode) fn,output); return; case FKind.FlatSetElementNode: - generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output); + generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output); return; case FKind.FlatSetFieldNode: - generateFlatSetFieldNode(fm, (FlatSetFieldNode) fn,output); + generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output); return; case FKind.FlatNew: - generateFlatNew(fm, (FlatNew) fn,output); + generateFlatNew(fm, lb, (FlatNew) fn,output); return; case FKind.FlatOpNode: - generateFlatOpNode(fm, (FlatOpNode) fn,output); + generateFlatOpNode(fm, lb, (FlatOpNode) fn,output); return; case FKind.FlatCastNode: - generateFlatCastNode(fm, (FlatCastNode) fn,output); + generateFlatCastNode(fm, lb, (FlatCastNode) fn,output); return; case FKind.FlatLiteralNode: - generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output); + generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output); return; case FKind.FlatReturnNode: - generateFlatReturnNode(fm, (FlatReturnNode) fn,output); + generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output); return; case FKind.FlatNop: output.println("/* nop */"); return; case FKind.FlatBackEdge: - if (state.THREAD&&GENERATEPRECISEGC) { - output.println("checkcollect(&"+localsprefix+");"); + if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) { + if(state.DSM&&locality.getAtomic(lb).get(fn).intValue()>0) { + output.println("checkcollect2(&"+localsprefix+",trans);"); + } else + output.println("checkcollect(&"+localsprefix+");"); } else output.println("/* nop */"); return; case FKind.FlatCheckNode: - generateFlatCheckNode(fm, (FlatCheckNode) fn, output); + generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output); return; case FKind.FlatFlagActionNode: - generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output); + generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output); + return; + case FKind.FlatPrefetchNode: + generateFlatPrefetchNode(fm,lb, (FlatPrefetchNode) fn, output); return; } throw new Error(); + } + + public void generateFlatPrefetchNode(FlatMethod fm, LocalityBinding lb, FlatPrefetchNode fpn, PrintWriter output) { + if (state.PREFETCH) { + Vector oids = new Vector(); + Vector fieldoffset = new Vector(); + Vector endoffset = new Vector(); + int tuplecount = 0; //Keeps track of number of prefetch tuples that need to be generated + for(Iterator it = fpn.hspp.iterator();it.hasNext();) { + PrefetchPair pp = (PrefetchPair) it.next(); + Integer statusbase = locality.getNodePreTempInfo(lb,fpn).get(pp.base); + /* Find prefetches that can generate oid */ + if(statusbase == LocalityAnalysis.GLOBAL) { + generateTransCode(fm, lb, pp, oids, fieldoffset, endoffset, tuplecount, locality.getAtomic(lb).get(fpn).intValue()>0, false); + tuplecount++; + } else if (statusbase == LocalityAnalysis.LOCAL) { + generateTransCode(fm,lb,pp,oids,fieldoffset,endoffset,tuplecount,false,true); + } else { + continue; + } + } + if (tuplecount==0) + return; + output.println("{"); + output.println("/* prefetch */"); + output.println("/* prefetchid_" + fpn.siteid + " */"); + output.println("void * prefptr;"); + output.println("int tmpindex;"); + + output.println("if((evalPrefetch["+fpn.siteid+"].operMode) || (evalPrefetch["+fpn.siteid+"].retrycount <= 0)) {"); + /*Create C code for oid array */ + output.print(" unsigned int oidarray_[] = {"); + boolean needcomma=false; + for (Iterator it = oids.iterator();it.hasNext();) { + if (needcomma) + output.print(", "); + output.print(it.next()); + needcomma=true; + } + output.println("};"); + + /*Create C code for endoffset values */ + output.print(" unsigned short endoffsetarry_[] = {"); + needcomma=false; + for (Iterator it = endoffset.iterator();it.hasNext();) { + if (needcomma) + output.print(", "); + output.print(it.next()); + needcomma=true; + } + output.println("};"); + + /*Create C code for Field Offset Values */ + output.print(" short fieldarry_[] = {"); + needcomma=false; + for (Iterator it = fieldoffset.iterator();it.hasNext();) { + if (needcomma) + output.print(", "); + output.print(it.next()); + needcomma=true; + } + output.println("};"); + /* make the prefetch call to Runtime */ + output.println(" if(!evalPrefetch["+fpn.siteid+"].operMode) {"); + output.println(" evalPrefetch["+fpn.siteid+"].retrycount = RETRYINTERVAL;"); + output.println(" }"); + output.println(" prefetch("+fpn.siteid+" ,"+tuplecount+", oidarray_, endoffsetarry_, fieldarry_);"); + output.println(" } else {"); + output.println(" evalPrefetch["+fpn.siteid+"].retrycount--;"); + output.println(" }"); + output.println("}"); + } + } + + public void generateTransCode(FlatMethod fm, LocalityBinding lb,PrefetchPair pp, Vector oids, Vector fieldoffset, Vector endoffset, int tuplecount, boolean inside, boolean localbase) { + short offsetcount = 0; + int breakindex=0; + if (inside) { + breakindex=1; + } else if (localbase) { + for(;breakindexpp.desc.size()) //all local + return; + + TypeDescriptor lasttype=pp.base.getType(); + String basestr=generateTemp(fm, pp.base, lb); + String teststr=""; + boolean maybenull=fm.getMethod().isStatic()|| + !pp.base.equals(fm.getParameter(0)); + + for(int i=0;i"+fd.getSafeSymbol(); + } else { + basestr=basestr+"->"+fd.getSafeSymbol(); + maybenull=true; + } + lasttype=fd.getType(); + } else { + IndexDescriptor id=(IndexDescriptor)desc; + indexcheck="((tmpindex="; + for(int j=0;j=0)&&(tmpindex<((struct ArrayObject *)prefptr)->___length___)"; + + if (!teststr.equals("")) + teststr+="&&"; + teststr+="((prefptr="+basestr+")!= NULL) &&"+indexcheck; + basestr="((void **)(((char *) &(((struct ArrayObject *)prefptr)->___length___))+sizeof(int)))[tmpindex]"; + maybenull=true; + lasttype=lasttype.dereference(); + } + } + + String oid; + if (teststr.equals("")) { + oid="((unsigned int)"+basestr+")"; + } else { + oid="((unsigned int)(("+teststr+")?"+basestr+":NULL))"; + } + oids.add(oid); + + for(int i = breakindex; i < pp.desc.size(); i++) { + String newfieldoffset; + Object desc = pp.getDescAt(i); + if(desc instanceof FieldDescriptor) { + FieldDescriptor fd=(FieldDescriptor)desc; + newfieldoffset = new String("(unsigned int)(&(((struct "+ lasttype.getSafeSymbol()+" *)0)->"+ fd.getSafeSymbol()+ "))"); + lasttype=fd.getType(); + } else { + newfieldoffset = ""; + IndexDescriptor id=(IndexDescriptor)desc; + for(int j = 0; j < id.tddesc.size(); j++) { + newfieldoffset += generateTemp(fm, id.getTempDescAt(j), lb) + "+"; + } + newfieldoffset += id.offset.toString(); + lasttype=lasttype.dereference(); + } + fieldoffset.add(newfieldoffset); + } + + int base=(tuplecount>0)?((Short)endoffset.get(tuplecount-1)).intValue():0; + base+=pp.desc.size()-breakindex; + endoffset.add(new Short((short)base)); + } + + + + public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) { + if (lb!=fgcn.getLocality()) + return; + /* Have to generate flat globalconv */ + if (fgcn.getMakePtr()) { + output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)transRead(trans, (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");"); + } else { + /* Need to convert to OID */ + output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");"); + } + } + + public void generateFlatAtomicEnterNode(FlatMethod fm, LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) { + /* Check to see if we need to generate code for this atomic */ + if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0) + return; + /* Backup the temps. */ + for(Iterator tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) { + TempDescriptor tmp=tmpit.next(); + output.println(generateTemp(fm, backuptable.get(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";"); + } + output.println("goto transstart"+faen.getIdentifier()+";"); + + /******* Print code to retry aborted transaction *******/ + output.println("transretry"+faen.getIdentifier()+":"); + + /* Restore temps */ + for(Iterator tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) { + TempDescriptor tmp=tmpit.next(); + output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(tmp),lb)+";"); + } + /********* Need to revert local object store ********/ + String revertptr=generateTemp(fm, reverttable.get(lb),lb); + + output.println("while ("+revertptr+") {"); + output.println("struct ___Object___ * tmpptr;"); + output.println("tmpptr="+revertptr+"->"+nextobjstr+";"); + output.println("REVERT_OBJ("+revertptr+");"); + output.println(revertptr+"=tmpptr;"); + output.println("}"); + + /******* Tell the runtime to start the transaction *******/ + + output.println("transstart"+faen.getIdentifier()+":"); + output.println("trans=transStart();"); } - private void generateFlatCheckNode(FlatMethod fm, FlatCheckNode fcn, PrintWriter output) { + public void generateFlatAtomicExitNode(FlatMethod fm, LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) { + /* Check to see if we need to generate code for this atomic */ + if (locality.getAtomic(lb).get(faen).intValue()>0) + return; + //store the revert list before we lose the transaction object + String revertptr=generateTemp(fm, reverttable.get(lb),lb); + output.println(revertptr+"=trans->revertlist;"); + output.println("if (transCommit(trans)) {"); + /* Transaction aborts if it returns true */ + output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";"); + output.println("} else {"); + /* Need to commit local object store */ + output.println("while ("+revertptr+") {"); + output.println("struct ___Object___ * tmpptr;"); + output.println("tmpptr="+revertptr+"->"+nextobjstr+";"); + output.println("COMMIT_OBJ("+revertptr+");"); + output.println(revertptr+"=tmpptr;"); + output.println("}"); + output.println("}"); + } + private void generateFlatCheckNode(FlatMethod fm, LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) { if (state.CONSCHECK) { String specname=fcn.getSpec(); String varname="repairstate___"; @@ -1152,7 +1723,7 @@ public class BuildCode { TempDescriptor[] temps=fcn.getTemps(); String[] vars=fcn.getVars(); for(int i=0;i"+vars[i]+"=(int)"+generateTemp(fm, temps[i])+";"); + output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i],lb)+";"); } output.println("if (doanalysis"+specname+"("+varname+")) {"); @@ -1162,26 +1733,34 @@ public class BuildCode { output.println("free"+specname+"_state("+varname+");"); output.println("abort_task();"); output.println("}"); - output.println("}"); } } - private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) { + private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) { MethodDescriptor md=fc.getMethod(); - ParamsObject objectparams=(ParamsObject) paramstable.get(md); + ParamsObject objectparams=(ParamsObject)paramstable.get(state.DSM?locality.getBinding(lb, fc):md); ClassDescriptor cn=md.getClassDesc(); output.println("{"); if (GENERATEPRECISEGC) { - output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + if (state.DSM) { + LocalityBinding fclb=locality.getBinding(lb, fc); + output.print(" struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); + } else + output.print(" struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={"); output.print(objectparams.numPointers()); - // output.print(objectparams.getUID()); output.print(", & "+localsprefix); - if (fc.getThis()!=null) { + if (md.getThis()!=null) { output.print(", "); - output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis())); + output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb)); } + if (fc.getThis()!=null&&md.getThis()==null) { + System.out.println("WARNING!!!!!!!!!!!!"); + System.out.println("Source code calls static method"+md+"on an object in "+fm.getMethod()+"!"); + } + + for(int i=0;itype*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])"); + if (state.DSM&&locality.getBinding(lb,fc).isAtomic()&&!fc.getMethod().getModifiers().isNative()) { + LocalityBinding fclb=locality.getBinding(lb, fc); + if (printcomma) + output.print(", "); + output.print("transrecord_t *"); + printcomma=true; + } + + if (state.DSM) { + LocalityBinding fclb=locality.getBinding(lb, fc); + output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])"); + } else + output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])"); } output.print("("); @@ -1241,15 +1841,27 @@ public class BuildCode { if (GENERATEPRECISEGC) { output.print("&__parameterlist__"); needcomma=true; - } else { + } + + if (state.DSM&&locality.getBinding(lb,fc).isAtomic()&&!fc.getMethod().getModifiers().isNative()) { + if (needcomma) + output.print(","); + output.print("trans"); + needcomma=true; + } + + if (!GENERATEPRECISEGC) { if (fc.getThis()!=null) { TypeDescriptor ptd=md.getThis().getType(); + if (needcomma) + output.print(","); if (ptd.isClass()&&!ptd.isArray()) output.print("(struct "+ptd.getSafeSymbol()+" *) "); - output.print(generateTemp(fm,fc.getThis())); + output.print(generateTemp(fm,fc.getThis(),lb)); needcomma=true; } } + for(int i=0;i"+ ffn.getField().getSafeSymbol()+";"); + private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) { + if (state.DSM) { + Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc()); + if (status==LocalityAnalysis.GLOBAL) { + String field=ffn.getField().getSafeSymbol(); + String src=generateTemp(fm, ffn.getSrc(),lb); + String dst=generateTemp(fm, ffn.getDst(),lb); + + if (ffn.getField().getType().isPtr()) { + + //TODO: Uncomment this when we have runtime support + //if (ffn.getSrc()==ffn.getDst()) { + //output.println("{"); + //output.println("void * temp="+src+";"); + //output.println("if (temp&0x1) {"); + //output.println("temp=(void *) transRead(trans, (unsigned int) temp);"); + //output.println(src+"->"+field+"="+temp+";"); + //output.println("}"); + //output.println(dst+"=temp;"); + //output.println("}"); + //} else { + output.println(dst+"="+ src +"->"+field+ ";"); + //output.println("if ("+dst+"&0x1) {"); + output.println(dst+"=(void *) transRead(trans, (unsigned int) "+dst+");"); + //output.println(src+"->"+field+"="+src+"->"+field+";"); + //output.println("}"); + //} + } else { + output.println(dst+"="+ src+"->"+field+";"); + } + } else if (status==LocalityAnalysis.LOCAL) { + output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); + } else if (status==LocalityAnalysis.EITHER) { + //Code is reading from a null pointer + output.println("if ("+generateTemp(fm, ffn.getSrc(),lb)+") {"); + output.println("#ifndef RAW"); + output.println("printf(\"BIG ERROR\\n\");exit(-1);}"); + output.println("#endif"); + //This should throw a suitable null pointer error + output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); + } else + throw new Error("Read from non-global/non-local in:"+lb.getExplanation()); + } else + output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); } - private void generateFlatSetFieldNode(FlatMethod fm, FlatSetFieldNode fsfn, PrintWriter output) { + + private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) { if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray()) throw new Error("Can't set array length"); - output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";"); + if (state.DSM && locality.getAtomic(lb).get(fsfn).intValue()>0) { + Integer statussrc=locality.getNodePreTempInfo(lb,fsfn).get(fsfn.getSrc()); + Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst()); + boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL; + + String src=generateTemp(fm,fsfn.getSrc(),lb); + String dst=generateTemp(fm,fsfn.getDst(),lb); + if (srcglobal) { + output.println("{"); + output.println("int srcoid=(int)"+src+"->"+oidstr+";"); + } + if (statusdst.equals(LocalityAnalysis.GLOBAL)) { + String glbdst=dst; + //mark it dirty + output.println("*((unsigned int *)&("+dst+"->___localcopy___))|=DIRTY;"); + if (srcglobal) { + output.println("*((unsigned int *)&("+glbdst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;"); + } else + output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";"); + } else if (statusdst.equals(LocalityAnalysis.LOCAL)) { + /** Check if we need to copy */ + output.println("if(!"+dst+"->"+localcopystr+") {"); + /* Link object into list */ + String revertptr=generateTemp(fm, reverttable.get(lb),lb); + output.println(revertptr+"=trans->revertlist;"); + if (GENERATEPRECISEGC) + output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");"); + else + output.println("COPY_OBJ("+dst+");"); + output.println(dst+"->"+nextobjstr+"="+revertptr+";"); + output.println("trans->revertlist=(struct ___Object___ *)"+dst+";"); + output.println("}"); + if (srcglobal) + output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;"); + else + output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";"); + } else if (statusdst.equals(LocalityAnalysis.EITHER)) { + //writing to a null...bad + output.println("if ("+dst+") {"); + output.println("#ifndef RAW"); + output.println("printf(\"BIG ERROR 2\\n\");exit(-1);}"); + output.println("#endif"); + if (srcglobal) + output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;"); + else + output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";"); + } + if (srcglobal) { + output.println("}"); + } + } else { + output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); + } } - private void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) { + private void generateFlatElementNode(FlatMethod fm, LocalityBinding lb, FlatElementNode fen, PrintWriter output) { TypeDescriptor elementtype=fen.getSrc().getType().dereference(); String type=""; @@ -1305,14 +2012,38 @@ public class BuildCode { type=elementtype.getSafeSymbol()+" "; if (fen.needsBoundsCheck()) { - output.println("if ("+generateTemp(fm, fen.getIndex())+"< 0 || "+generateTemp(fm, fen.getIndex())+" >= "+generateTemp(fm,fen.getSrc()) + "->___length___)"); + output.println("if ("+generateTemp(fm, fen.getIndex(),lb)+"< 0 || "+generateTemp(fm, fen.getIndex(),lb)+" >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___)"); output.println("failedboundschk();"); } - - output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];"); + if (state.DSM) { + Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc()); + if (status==LocalityAnalysis.GLOBAL) { + String dst=generateTemp(fm, fen.getDst(),lb); + + if (elementtype.isPtr()) { + output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];"); + output.println(dst+"=(void *) transRead(trans, (unsigned int) "+dst+");"); + } else { + output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];"); + } + } else if (status==LocalityAnalysis.LOCAL) { + output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];"); + } else if (status==LocalityAnalysis.EITHER) { + //Code is reading from a null pointer + output.println("if ("+generateTemp(fm, fen.getSrc(),lb)+") {"); + output.println("#ifndef RAW"); + output.println("printf(\"BIG ERROR\\n\");exit(-1);}"); + output.println("#endif"); + //This should throw a suitable null pointer error + output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];"); + } else + throw new Error("Read from non-global/non-local in:"+lb.getExplanation()); + } else { + output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];"); + } } - private void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) { + private void generateFlatSetElementNode(FlatMethod fm, LocalityBinding lb, FlatSetElementNode fsen, PrintWriter output) { //TODO: need dynamic check to make sure this assignment is actually legal //Because Object[] could actually be something more specific...ie. Integer[] @@ -1324,102 +2055,177 @@ public class BuildCode { else type=elementtype.getSafeSymbol()+" "; + if (fsen.needsBoundsCheck()) { - output.println("if ("+generateTemp(fm, fsen.getIndex())+"< 0 || "+generateTemp(fm, fsen.getIndex())+" >= "+generateTemp(fm,fsen.getDst()) + "->___length___)"); + output.println("if ("+generateTemp(fm, fsen.getIndex(),lb)+"< 0 || "+generateTemp(fm, fsen.getIndex(),lb)+" >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___)"); output.println("failedboundschk();"); } - output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";"); + if (state.DSM && locality.getAtomic(lb).get(fsen).intValue()>0) { + Integer statussrc=locality.getNodePreTempInfo(lb,fsen).get(fsen.getSrc()); + Integer statusdst=locality.getNodePreTempInfo(lb,fsen).get(fsen.getDst()); + boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL; + boolean dstglobal=statusdst==LocalityAnalysis.GLOBAL; + boolean dstlocal=statusdst==LocalityAnalysis.LOCAL; + + if (dstglobal) { + output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___localcopy___))|=DIRTY;"); + } else if (dstlocal) { + /** Check if we need to copy */ + String dst=generateTemp(fm, fsen.getDst(),lb); + output.println("if(!"+dst+"->"+localcopystr+") {"); + /* Link object into list */ + String revertptr=generateTemp(fm, reverttable.get(lb),lb); + output.println(revertptr+"=trans->revertlist;"); + if (GENERATEPRECISEGC) + output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");"); + else + output.println("COPY_OBJ("+dst+");"); + output.println(dst+"->"+nextobjstr+"="+revertptr+";"); + output.println("trans->revertlist=(struct ___Object___ *)"+dst+";"); + output.println("}"); + } else throw new Error("Unknown array type"); + if (srcglobal) { + output.println("{"); + String src=generateTemp(fm, fsen.getSrc(), lb); + output.println("int srcoid=(int)"+src+"->"+oidstr+";"); + output.println("((int*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;"); + output.println("}"); + } else { + output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";"); + } + } else + output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";"); } - private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) { + private void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) { + if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) { + //Stash pointer in case of GC + String revertptr=generateTemp(fm, reverttable.get(lb),lb); + output.println(revertptr+"=trans->revertlist;"); + } if (fn.getType().isArray()) { int arrayid=state.getArrayNumber(fn.getType())+state.numClasses(); - if (GENERATEPRECISEGC) { - output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");"); + if (fn.isGlobal()) { + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal(trans, "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");"); + } else if (GENERATEPRECISEGC) { + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");"); } else { - output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");"); + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");"); } } else { - if (GENERATEPRECISEGC) { - output.println(generateTemp(fm,fn.getDst())+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");"); + if (fn.isGlobal()) { + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal(trans, "+fn.getType().getClassDesc().getId()+");"); + } else if (GENERATEPRECISEGC) { + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");"); } else { - output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");"); + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");"); } } + if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) { + String revertptr=generateTemp(fm, reverttable.get(lb),lb); + output.println("trans->revertlist="+revertptr+";"); + } } - - private void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) { + private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) { if (GENERATEPRECISEGC) { - output.println(generateTemp(fm,fn.getDst())+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");"); + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");"); } else { - output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");"); + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");"); } } - private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) { + private void generateFlatOpNode(FlatMethod fm, LocalityBinding lb, FlatOpNode fon, PrintWriter output) { + if (fon.getRight()!=null) { + if (fon.getOp().getOp()==Operation.URIGHTSHIFT) { + if (fon.getLeft().getType().isLong()) + output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";"); + else + output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned int)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";"); - if (fon.getRight()!=null) - output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";"); - else if (fon.getOp().getOp()==Operation.ASSIGN) - output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";"); + } else + output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";"); + } else if (fon.getOp().getOp()==Operation.ASSIGN) + output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";"); else if (fon.getOp().getOp()==Operation.UNARYPLUS) - output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";"); + output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";"); else if (fon.getOp().getOp()==Operation.UNARYMINUS) - output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";"); + output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";"); else if (fon.getOp().getOp()==Operation.LOGIC_NOT) - output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";"); - else - output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";"); + output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";"); + else if (fon.getOp().getOp()==Operation.COMP) + output.println(generateTemp(fm, fon.getDest(),lb)+" = ~"+generateTemp(fm, fon.getLeft(),lb)+";"); + else if (fon.getOp().getOp()==Operation.ISAVAILABLE) { + output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+"->fses==NULL;"); + } else + output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";"); } - private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) { + private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) { /* TODO: Do type check here */ if (fcn.getType().isArray()) { throw new Error(); } else if (fcn.getType().isClass()) - output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";"); + output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";"); else - output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";"); + output.println(generateTemp(fm,fcn.getDst(),lb)+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc(),lb)+";"); } - private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) { + private void generateFlatLiteralNode(FlatMethod fm, LocalityBinding lb, FlatLiteralNode fln, PrintWriter output) { if (fln.getValue()==null) - output.println(generateTemp(fm, fln.getDst())+"=0;"); + output.println(generateTemp(fm, fln.getDst(),lb)+"=0;"); else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) { if (GENERATEPRECISEGC) { - output.println(generateTemp(fm, fln.getDst())+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");"); + if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) { + //Stash pointer in case of GC + String revertptr=generateTemp(fm, reverttable.get(lb),lb); + output.println(revertptr+"=trans->revertlist;"); + } + output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");"); + if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) { + //Stash pointer in case of GC + String revertptr=generateTemp(fm, reverttable.get(lb),lb); + output.println("trans->revertlist="+revertptr+";"); + } } else { - output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");"); + output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");"); } } else if (fln.getType().isBoolean()) { if (((Boolean)fln.getValue()).booleanValue()) - output.println(generateTemp(fm, fln.getDst())+"=1;"); + output.println(generateTemp(fm, fln.getDst(),lb)+"=1;"); else - output.println(generateTemp(fm, fln.getDst())+"=0;"); + output.println(generateTemp(fm, fln.getDst(),lb)+"=0;"); } else if (fln.getType().isChar()) { String st=FlatLiteralNode.escapeString(fln.getValue().toString()); - output.println(generateTemp(fm, fln.getDst())+"='"+st+"';"); + output.println(generateTemp(fm, fln.getDst(),lb)+"='"+st+"';"); + } else if (fln.getType().isLong()) { + output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+"LL;"); } else - output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";"); + output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";"); } - private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) { - - if (frn.getReturnTemp()!=null) - output.println("return "+generateTemp(fm, frn.getReturnTemp())+";"); - else + protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) { + if (frn.getReturnTemp()!=null) { + if (frn.getReturnTemp().getType().isPtr()) + output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";"); + else + output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";"); + } else { output.println("return;"); + } } - private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) { - output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";"); + protected void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) { + output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";"); } - private void generateHeader(FlatMethod fm, Descriptor des, PrintWriter output) { + /** This method generates header information for the method or + * task referenced by the Descriptor des. */ + + private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) { /* Print header */ - ParamsObject objectparams=(ParamsObject)paramstable.get(des); + ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:des); MethodDescriptor md=null; TaskDescriptor task=null; if (des instanceof MethodDescriptor) @@ -1437,20 +2243,33 @@ public class BuildCode { } else //catch the constructor case output.print("void "); - if (md!=null) - output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"("); - else + if (md!=null) { + if (state.DSM) { + output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"("); + } else + output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"("); + } else output.print(task.getSafeSymbol()+"("); boolean printcomma=false; if (GENERATEPRECISEGC) { - if (md!=null) - output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix); - else + if (md!=null) { + if (state.DSM) { + output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix); + } else + output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix); + } else output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix); printcomma=true; } + if (state.DSM&&lb.isAtomic()) { + if (printcomma) + output.print(", "); + output.print("transrecord_t * trans"); + printcomma=true; + } + if (md!=null) { /* Method */ for(int i=0;i slotnumber=new Hashtable(); + int current_slot=0; + + for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){ + VarDescriptor vard = (VarDescriptor)vard_it.next(); + TypeDescriptor typed = vard.getType(); + + //generate for flags + HashSet fen_hashset = predicate.flags.get(vard.getSymbol()); + output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={"); + int numberterms=0; + if (fen_hashset!=null){ + for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){ + FlagExpressionNode fen = (FlagExpressionNode)fen_it.next(); + if (fen!=null) { + DNFFlag dflag=fen.getDNF(); + numberterms+=dflag.size(); + + Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc()); + + for(int j=0;j>> safeexecution, Hashtable optionaltaskdescriptors) { + generateOptionalHeader(headers); + //GENERATE STRUCTS + output.println("#include \"optionalstruct.h\"\n\n"); + output.println("#include \"stdlib.h\"\n"); + + HashSet processedcd = new HashSet(); + int maxotd=0; + Enumeration e = safeexecution.keys(); + while (e.hasMoreElements()) { + int numotd=0; + //get the class + ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement(); + Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times + + //Generate the struct of optionals + Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values(); + numotd = c_otd.size(); + if(maxotd fsset=new TreeSet(); + //iterate through possible FSes corresponding to + //the state when entering + + for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext();){ + FlagState fs = (FlagState)fses.next(); + int flagid=0; + for(Iterator flags = fs.getFlags(); flags.hasNext();){ + FlagDescriptor flagd = (FlagDescriptor)flags.next(); + int id=1<<((Integer)flaginfo.get(flagd)).intValue(); + flagid|=id; + } + fsset.add(new Integer(flagid)); + //tag information not needed because tag + //changes are not tolerated. + } + + output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={"); + boolean needcomma=false; + for(Iterator it=fsset.iterator();it.hasNext();) { + if(needcomma) + output.print(", "); + output.println(it.next()); + } + + output.println("};\n"); + + + //generate optionaltaskdescriptor that actually + //includes exit fses, predicate and the task + //concerned + output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={"); + output.println("&task_"+otd.td.getSafeSymbol()+","); + output.println("/*index*/"+otd.getIndex()+","); + output.println("/*number of enter flags*/"+fsset.size()+","); + output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+","); + output.println("/*number of members */"+predicateindex+","); + output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+","); + output.println("};\n"); + } + } else + continue; + // if there are no optionals, there is no need to build the rest of the struct + + output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={"); + c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values(); + if( !c_otd.isEmpty() ){ + boolean needcomma=false; + for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){ + OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next(); + if(needcomma) + output.println(","); + needcomma=true; + output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()); + } + } + output.println("};\n"); + + //get all the possible flagstates reachable by an object + Hashtable hashtbtemp = safeexecution.get(cdtemp); + int fscounter = 0; + TreeSet fsts=new TreeSet(new FlagComparator(flaginfo)); + fsts.addAll(hashtbtemp.keySet()); + for(Iterator fsit=fsts.iterator();fsit.hasNext();) { + FlagState fs = (FlagState)fsit.next(); + fscounter++; + + //get the set of OptionalTaskDescriptors corresponding + HashSet availabletasks = (HashSet)hashtbtemp.get(fs); + //iterate through the OptionalTaskDescriptors and + //store the pointers to the optionals struct (see on + //top) into an array + + output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {"); + for(Iterator mos = ordertd(availabletasks).iterator(); mos.hasNext();){ + OptionalTaskDescriptor mm = mos.next(); + if(!mos.hasNext()) + output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()); + else + output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+","); + } + + output.println("};\n"); + + //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose. + + int flagid=0; + for(Iterator flags = fs.getFlags(); flags.hasNext();){ + FlagDescriptor flagd = (FlagDescriptor)flags.next(); + int id=1<<((Integer)flaginfo.get(flagd)).intValue(); + flagid|=id; + } + + //process tag information + + int tagcounter = 0; + boolean first = true; + Enumeration tag_enum = fs.getTags(); + output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={"); + while(tag_enum.hasMoreElements()){ + tagcounter++; + TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement(); + if(first==true) + first = false; + else + output.println(", "); + output.println("/*tagid*/"+state.getTagId(tagd)); + } + output.println("};"); + + Set tiset=sa.getTaskIndex(fs); + for(Iterator itti=tiset.iterator();itti.hasNext();) { + TaskIndex ti=itti.next(); + if (ti.isRuntime()) + continue; + + Set otdset=sa.getOptions(fs, ti); + + output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {"); + boolean needcomma=false; + for(Iterator otdit=ordertd(otdset).iterator();otdit.hasNext();) { + OptionalTaskDescriptor otd=otdit.next(); + if(needcomma) + output.print(", "); + needcomma=true; + output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()); + } + output.println("};"); + + output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {"); + output.print("&task_"+ti.getTask().getSafeSymbol()+", "); + output.print(ti.getIndex()+", "); + output.print(otdset.size()+", "); + output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array"); + output.println("};"); + } + + tiset=sa.getTaskIndex(fs); + boolean needcomma=false; + int runtimeti=0; + output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={"); + for(Iterator itti=tiset.iterator();itti.hasNext();) { + TaskIndex ti=itti.next(); + if (ti.isRuntime()) { + runtimeti++; + continue; + } + if (needcomma) + output.print(", "); + needcomma=true; + output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()); + } + output.println("};\n"); + + //Store the result in fsanalysiswrapper + + output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={"); + output.println("/*flag*/"+flagid+","); + output.println("/* number of tags*/"+tagcounter+","); + output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+","); + output.println("/* numtask failures */"+(tiset.size()-runtimeti)+","); + output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+","); + output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+","); + output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()); + output.println("};\n"); + + } + + //Build the array of fsanalysiswrappers + output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {"); + boolean needcomma=false; + for(int i = 0; i0) + output.print(", "); + if (processedcd.contains(cn)) + output.print("&classanalysiswrapper_"+cn.getSafeSymbol()); + else + output.print("NULL"); + } + output.println("};"); + + output.println("#define MAXOTD "+maxotd); + headers.println("#endif"); } + public List ordertd(Set otdset) { + Relation r=new Relation(); + for(Iteratorotdit=otdset.iterator();otdit.hasNext();) { + OptionalTaskDescriptor otd=otdit.next(); + TaskIndex ti=new TaskIndex(otd.td, otd.getIndex()); + r.put(ti, otd); + } + + LinkedList l=new LinkedList(); + for(Iterator it=r.keySet().iterator();it.hasNext();) { + Set s=r.get(it.next()); + for(Iterator it2=s.iterator();it2.hasNext();) { + OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next(); + l.add(otd); + } + } + + return l; + } + + protected void outputTransCode(PrintWriter output) { + } }