added dsmdebug file for debugging using macros and setting flags in buildscript
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
index 96f6d96e1a220fc75395dd9f70cd1df6c1c6f188..8781ff4e3ca832db40545acb02f3d86ce2a20c59 100644 (file)
@@ -6,9 +6,17 @@ import IR.Tree.TagExpressionList;
 import IR.*;
 import java.util.*;
 import java.io.*;
+
 import Util.Relation;
 import Analysis.TaskStateAnalysis.FlagState;
-import Analysis.TaskStateAnalysis.MyOptional;
+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;
@@ -20,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;
-   
-    public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
+    LocalityAnalysis locality;
+    Hashtable<TempDescriptor, TempDescriptor> backuptable;
+    Hashtable<LocalityBinding, TempDescriptor> 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, 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<TempDescriptor, TempDescriptor>();
+           this.reverttable=new Hashtable<LocalityBinding, TempDescriptor>();
+       }
     }
 
     /** The buildCode method outputs C code for all the methods.  The Flat
@@ -55,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();
@@ -89,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()));
-
-
-       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 Structures */
+       outputStructs(outstructs);
 
-       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 <pthread.h>");
-
-       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();
@@ -202,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<argc;i++) {");
+       } else 
+           outmethod.println("  for(i=1;i<argc;i++) {");
+       outmethod.println("    int length=strlen(argv[i]);");
+       if (GENERATEPRECISEGC) {
+           outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
+       } else {
+           outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
+       }
+       if (state.DSM)
+           outmethod.println("    ((void **)(((char *)& stringarray->___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 <runtime.h>");
-       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 <thread.h>");
        if (state.main!=null) {
            outmethod.println("#include <string.h>");       
        }
-
        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);
        
@@ -236,116 +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<LocalityBinding> 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<argc;i++) {");
-           outmethod.println("    int length=strlen(argv[i]);");
-           if (GENERATEPRECISEGC) {
-               outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
-           } else {
-               outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
-           }
-           outmethod.println("    ((void **)(((char *)& stringarray->___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()));
 
-           MethodDescriptor md=typeutil.getMain();
-           ClassDescriptor cd=typeutil.getMainClass();
+       outstructs.println("#define OBJECTARRAYTYPE "+
+                          (state.getArrayNumber(
+                                                (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
 
-           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);
 
-       if (state.TASK&&state.OPTIONAL){
-           generateOptionalArrays(outoptionalarrays, state.getAnalysisResult(), state.getMyOptionals());
-           outoptionalarrays.close();
-       } 
+       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();
+    protected void outputClassDeclarations(PrintWriter outclassdefs) {
+       if (state.THREAD||state.DSM)
+           outclassdefs.println("#include <pthread.h>");
+       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();
@@ -355,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");
@@ -377,7 +516,6 @@ public class BuildCode {
            */
            outrepairstructs.println("}\n");
        }
-
     }
 
     private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
@@ -401,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;i<task.numParameters();i++) {
            VarDescriptor param_var=task.getParameter(i);
            TypeDescriptor param_type=task.getParamType(i);
@@ -414,7 +552,6 @@ public class BuildCode {
                output.println("0x0, 0x0 };");
                dnfterms=1;
            } else {
-
                DNFFlag dflag=param_flag.getDNF();
                dnfterms=dflag.size();
                
@@ -493,21 +630,29 @@ public class BuildCode {
 
     /** The buildVirtualTables method outputs the virtual dispatch
      * tables for methods. */
-
-    private void buildVirtualTables(PrintWriter outvirtual) {
+    
+    protected void buildVirtualTables(PrintWriter outvirtual) {
        Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
        while(classit.hasNext()) {
            ClassDescriptor cd=(ClassDescriptor)classit.next();
            if (virtualcalls.getMethodCount(cd)>maxcount)
                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);
@@ -515,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[]={");
@@ -524,7 +672,11 @@ public class BuildCode {
            for(int j=0;j<maxcount;j++) {
                if (needcomma)
                    outvirtual.print(", ");
-               if (virtualtable[i][j]!=null) {
+               if (state.DSM&&lbvirtualtable[i][j]!=null) {
+                   LocalityBinding lb=lbvirtualtable[i][j];
+                   MethodDescriptor md=lb.getMethod();
+                   outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
+               } else if (!state.DSM&&virtualtable[i][j]!=null) {
                    MethodDescriptor md=virtualtable[i][j];
                    outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
                } else {
@@ -552,12 +704,42 @@ public class BuildCode {
        }
     }
 
+    private void fillinRow(ClassDescriptor cd, LocalityBinding[][] virtualtable, int rownum) {
+       /* Get inherited methods */
+       if (cd.getSuperDesc()!=null)
+           fillinRow(cd.getSuperDesc(), virtualtable, rownum);
+       /* Override them with our methods */
+       if (locality.getClassBindings(cd)!=null)
+           for(Iterator<LocalityBinding> 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()) {
@@ -599,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<TempDescriptor> 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);
@@ -612,10 +797,13 @@ public class BuildCode {
        for(int i=0;i<fm.numParameters();i++) {
            TempDescriptor temp=fm.getParameter(i);
            TypeDescriptor type=temp.getType();
-           if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
+           if (type.isPtr()&&GENERATEPRECISEGC)
                objectparams.addPtr(temp);
            else
                objectparams.addPrim(temp);
+           if(lb!=null&&saveset.contains(temp)) {
+               backuptable.put(temp, temp.createNew());
+           }
        }
 
        for(int i=0;i<fm.numTags();i++) {
@@ -627,7 +815,9 @@ public class BuildCode {
        }
 
        TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
-       if (md!=null)
+       if (lb!=null)
+           tempstable.put(lb, objecttemps);
+       else if (md!=null)
            tempstable.put(md, objecttemps);
        else
            tempstable.put(task, objecttemps);
@@ -638,25 +828,58 @@ public class BuildCode {
            for(int i=0;i<writes.length;i++) {
                TempDescriptor temp=writes[i];
                TypeDescriptor type=temp.getType();
-               if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
+               if (type.isPtr()&&GENERATEPRECISEGC)
                    objecttemps.addPtr(temp);
                else
                    objecttemps.addPrim(temp);
+               if(lb!=null&&saveset.contains(temp)&&
+                  !backuptable.containsKey(temp))
+                   backuptable.put(temp, temp.createNew());
+           }
+       }
+
+       /* Create backup temps */
+       if (lb!=null) {
+           for(Iterator<TempDescriptor> 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);
@@ -664,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<state.numClasses();i++) {
            ClassDescriptor cn=cdarray[i];
@@ -686,7 +911,7 @@ public class BuildCode {
                output.println(", ");
            TypeDescriptor tdelement=arraytable[i].dereference();
            if (tdelement.isArray()||tdelement.isClass())
-               output.print("((int *)1)");
+               output.print("((unsigned int *)1)");
            else
                output.print("0");
            needcomma=true;
@@ -729,6 +954,7 @@ public class BuildCode {
     /** Force consistent field ordering between inherited classes. */
 
     private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
+       
        ClassDescriptor sp=cn.getSuperDesc();
        if (sp!=null)
            printClassStruct(sp, classdefout);
@@ -736,10 +962,14 @@ public class BuildCode {
        if (!fieldorder.containsKey(cn)) {
            Vector fields=new Vector();
            fieldorder.put(cn,fields);
+           if (sp==null&&!state.TASK) {
+               fields.add(cn.getFieldTable().get("cachedCode"));
+           }
            Iterator fieldit=cn.getFields();
            while(fieldit.hasNext()) {
                FieldDescriptor fd=(FieldDescriptor)fieldit.next();
-               if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
+               if ((sp==null||!sp.getFieldTable().contains(fd.getSymbol()))&&
+                   (!fd.getSymbol().equals("cachedCode")||state.TASK))
                    fields.add(fd);
            }
        }
@@ -758,7 +988,7 @@ public class BuildCode {
     /* Map flags to integers consistently between inherited
      * classes. */
 
-    private void mapFlags(ClassDescriptor cn) {
+    protected void mapFlags(ClassDescriptor cn) {
        ClassDescriptor sp=cn.getSuperDesc();
        if (sp!=null)
            mapFlags(sp);
@@ -792,7 +1022,7 @@ public class BuildCode {
      * passed in (when PRECISE GC is enabled) and (2) function
      * prototypes for the methods */
 
-    private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
+    protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
        /* Output class structure */
        classdefout.println("struct "+cn.getSafeSymbol()+" {");
        classdefout.println("  int type;");
@@ -804,81 +1034,150 @@ public class BuildCode {
 
        if (state.TASK) {
            classdefout.println("  int flag;");
-           classdefout.println("  void * flagptr;");
-           classdefout.println("  int failedstatus;");
-           classdefout.println("  int * flagset;");
+           if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
+               classdefout.println("  void * flagptr;");
+           } else if (state.MULTICORE){
+               classdefout.println("  int isolate;"); // indicate if this object is shared or not
+               classdefout.println("  int version;");
+               classdefout.println("  struct ___Object___ * original;");
+           }
+           if (state.OPTIONAL){
+               classdefout.println("  int numfses;");
+               classdefout.println("  int * fses;");
+           }
        }
        printClassStruct(cn, classdefout);
        classdefout.println("};\n");
 
-       /* Cycle through methods */
-       Iterator methodit=cn.getMethods();
-       while(methodit.hasNext()) {
-           /* Classify parameters */
-           MethodDescriptor md=(MethodDescriptor)methodit.next();
-           FlatMethod fm=state.getMethodFlat(md);
-           generateTempStructs(fm);
+       if (state.DSM) {
+           /* Cycle through LocalityBindings */
+           HashSet<MethodDescriptor> nativemethods=new HashSet<MethodDescriptor>();
+           Set<LocalityBinding> lbset=locality.getClassBindings(cn);
+           if (lbset!=null) {
+               for(Iterator<LocalityBinding> 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;i<objectparams.numPointers();i++) {
-                   TempDescriptor temp=objectparams.getPointer(i);
-                   output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
-               }
-               output.println("};\n");
+           output.println("  int size;");
+           output.println("  void * next;");
+           for(int i=0;i<objectparams.numPointers();i++) {
+               TempDescriptor temp=objectparams.getPointer(i);
+               output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
            }
+           output.println("};\n");
+       }
+    }
 
-           /* Output temp structure */
-           if (GENERATEPRECISEGC) {
+
+    private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
+       FlatMethod fm=state.getMethodFlat(md);
+       generateTempStructs(fm, lb);
+       
+       ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null?lb:md);
+       TempObject objecttemps=(TempObject) tempstable.get(lb!=null?lb:md);
+       
+       generateMethodParam(cn, md, lb, output);
+       
+       /* Output temp structure */
+       if (GENERATEPRECISEGC) {
+           if (state.DSM)
+               output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
+           else
                output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
-               output.println("  int size;");
-               output.println("  void * next;");
-               for(int i=0;i<objecttemps.numPointers();i++) {
-                   TempDescriptor temp=objecttemps.getPointer(i);
-                   if (temp.getType().isNull())
-                       output.println("  void * "+temp.getSafeSymbol()+";");
-                   else
-                       output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
-               }
-               output.println("};\n");
-           }
-           
-           /* Output method declaration */
-           if (md.getReturnType()!=null) {
-               if (md.getReturnType().isClass()||md.getReturnType().isArray())
-                   headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
+           output.println("  int size;");
+           output.println("  void * next;");
+           for(int i=0;i<objecttemps.numPointers();i++) {
+               TempDescriptor temp=objecttemps.getPointer(i);
+               if (temp.getType().isNull())
+                   output.println("  void * "+temp.getSafeSymbol()+";");
                else
-                   headersout.print(md.getReturnType().getSafeSymbol()+" ");
-           } else 
-               //catch the constructor case
-               headersout.print("void ");
+                   output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
+           }
+           output.println("};\n");
+       }
+       
+       /********* Output method declaration ***********/
+
+       /* First the return type */
+       if (md.getReturnType()!=null) {
+           if (md.getReturnType().isClass()||md.getReturnType().isArray())
+               headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
+           else
+               headersout.print(md.getReturnType().getSafeSymbol()+" ");
+       } else 
+           //catch the constructor case
+           headersout.print("void ");
+
+       /* Next the method name */
+       if (state.DSM) {
+           headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
+       } else
            headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
-           
-           boolean printcomma=false;
-           if (GENERATEPRECISEGC) {
+       
+       boolean printcomma=false;
+       if (GENERATEPRECISEGC) {
+           if (state.DSM) {
+               headersout.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
+           } else
                headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
-               printcomma=true;
-           }
+           printcomma=true;
+       }
+       
+       if (state.DSM&&lb.isAtomic()&&!md.getModifiers().isNative()) {
+           if (printcomma)
+               headersout.print(", ");
+           headersout.print("transrecord_t * trans");
+           printcomma=true;
+       }
 
-           //output parameter list
-           for(int i=0;i<objectparams.numPrimitives();i++) {
-               TempDescriptor temp=objectparams.getPrimitive(i);
-               if (printcomma)
-                   headersout.print(", ");
-               printcomma=true;
-               if (temp.getType().isClass()||temp.getType().isArray())
-                   headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
-               else
-                   headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
-           }
-           headersout.println(");\n");
-       }
+       /*  Output parameter list*/
+       for(int i=0;i<objectparams.numPrimitives();i++) {
+           TempDescriptor temp=objectparams.getPrimitive(i);
+           if (printcomma)
+               headersout.print(", ");
+           printcomma=true;
+           if (temp.getType().isClass()||temp.getType().isArray())
+               headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
+           else
+               headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
+       }
+       headersout.println(");\n");
     }
 
 
@@ -894,7 +1193,7 @@ public class BuildCode {
            /* Classify parameters */
            TaskDescriptor task=(TaskDescriptor)taskit.next();
            FlatMethod fm=state.getMethodFlat(task);
-           generateTempStructs(fm);
+           generateTempStructs(fm, null);
 
            ParamsObject objectparams=(ParamsObject) paramstable.get(task);
            TempObject objecttemps=(TempObject) tempstable.get(task);
@@ -946,81 +1245,68 @@ public class BuildCode {
        }
     }
 
-    /** Generate code for flatmethod fm. */
+    /***** Generate code for FlatMethod fm. *****/
 
-    private void generateFlatMethod(FlatMethod fm, PrintWriter output) {
+    private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
+       if (State.PRINTFLAT)
+           System.out.println(fm.printMethod());
        MethodDescriptor md=fm.getMethod();
+       
        TaskDescriptor task=fm.getTask();
 
                ClassDescriptor cn=md!=null?md.getClassDesc():null;
 
-       ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
-
-       generateHeader(fm, md!=null?md:task,output);
-
-       TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
+       ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:md!=null?md:task);
+       generateHeader(fm, lb, md!=null?md:task,output);
+       TempObject objecttemp=(TempObject) tempstable.get(lb!=null?lb:md!=null?md:task);
+       if (state.DSM&&lb.getHasAtomic()) {
+           output.println("transrecord_t * trans;");
+       }
 
-       /* Print code */
        if (GENERATEPRECISEGC) {
-           if (md!=null)
+           if (md!=null&&state.DSM)
+               output.print("   struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
+           else if (md!=null&&!state.DSM)
                output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
            else
-               output.print("   struct "+task.getSafeSymbol()+"_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 (type.isClass()||type.isArray())
-               output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
-           else
-               output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
-       }
-
-       /* Generate labels first */
-       HashSet tovisit=new HashSet();
-       HashSet visited=new HashSet();
-       int labelindex=0;
-       Hashtable nodetolabel=new Hashtable();
-       tovisit.add(fm.getNext(0));
-       FlatNode current_node=null;
-
-       //Assign labels 1st
-       //Node needs a label if it is
-       while(!tovisit.isEmpty()) {
-           FlatNode fn=(FlatNode)tovisit.iterator().next();
-           tovisit.remove(fn);
-           visited.add(fn);
-           for(int i=0;i<fn.numNext();i++) {
-               FlatNode nn=fn.getNext(i);
-               if(i>0) {
-                   //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++));
-               }
-           }
+               output.print("   struct "+task.getSafeSymbol()+"_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 (type.isClass()||type.isArray())
+               output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
+           else
+               output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
        }
 
-       if (state.THREAD&&GENERATEPRECISEGC) {
-           output.println("checkcollect(&"+localsprefix+");");
+       /* Assign labels to FlatNode's if necessary.*/
+
+       Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm);
+
+       /* Check to see if we need to do a GC if this is a
+        * multi-threaded program...*/
+
+       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) {
@@ -1031,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
@@ -1039,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)+";");
@@ -1056,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))) {
@@ -1066,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<FlatNode, Integer> assignLabels(FlatMethod fm) {
+       HashSet tovisit=new HashSet();
+       HashSet visited=new HashSet();
+       int labelindex=0;
+       Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
+       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;i<fn.numNext();i++) {
+               FlatNode nn=fn.getNext(i);
+               if(i>0) {
+                   //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();
@@ -1091,76 +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, (FlatAtomicEnterNode) fn, output);
+           generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
            return;
        case FKind.FlatAtomicExitNode:
-           generateFlatAtomicExitNode(fm, (FlatAtomicExitNode) fn, output);
+           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(;breakindex<pp.desc.size();breakindex++) {
+               Descriptor desc=pp.getDescAt(breakindex);
+               if (desc instanceof FieldDescriptor) {
+                   FieldDescriptor fd=(FieldDescriptor)desc;
+                   if (fd.isGlobal()) {
+                       break;
+                   }
+               }
+           }
+           breakindex++;
+       }
+
+       if (breakindex>pp.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<breakindex;i++) {
+           String indexcheck="";
+
+           Descriptor desc=pp.getDescAt(i);
+           if (desc instanceof FieldDescriptor) {
+               FieldDescriptor fd=(FieldDescriptor)desc;
+               if (maybenull) {
+                   if (!teststr.equals(""))
+                       teststr+="&&";
+                   teststr+="((prefptr="+basestr+")!=NULL)";
+                   basestr="((struct "+lasttype.getSafeSymbol()+" *)prefptr)->"+fd.getSafeSymbol();
+               } else {
+                   basestr=basestr+"->"+fd.getSafeSymbol();
+                   maybenull=true;
+               }
+               lasttype=fd.getType();
+           } else {
+               IndexDescriptor id=(IndexDescriptor)desc;
+               indexcheck="((tmpindex=";
+               for(int j=0;j<id.tddesc.size();j++) {
+                   indexcheck+=generateTemp(fm, id.getTempDescAt(j), lb)+"+";
+               }
+               indexcheck+=id.offset+")>=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 generateFlatAtomicEnterNode(FlatMethod fm,  FlatAtomicEnterNode faen, PrintWriter output) {
+
+  
+    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 generateFlatAtomicExitNode(FlatMethod fm,  FlatAtomicExitNode faen, PrintWriter output) {
+    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<TempDescriptor> 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<TempDescriptor> 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___";
@@ -1170,7 +1723,7 @@ public class BuildCode {
            TempDescriptor[] temps=fcn.getTemps();
            String[] vars=fcn.getVars();
            for(int i=0;i<temps.length;i++) {
-               output.println(varname+"->"+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+")) {");
@@ -1180,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;i<fc.numArgs();i++) {
                Descriptor var=md.getParameter(i);
                TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
@@ -1208,9 +1769,9 @@ public class BuildCode {
                    output.print(", ");
                    TypeDescriptor td=md.getParamType(i);
                    if (td.isTag())
-                       output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
+                       output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
                    else
-                       output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
+                       output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
                }
            }
            output.println("};");
@@ -1219,13 +1780,19 @@ public class BuildCode {
 
 
        if (fc.getReturnTemp()!=null)
-           output.print(generateTemp(fm,fc.getReturnTemp())+"=");
+           output.print(generateTemp(fm,fc.getReturnTemp(),lb)+"=");
 
        /* Do we need to do virtual dispatch? */
        if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
-           output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
+           //no
+           if (state.DSM) {
+               LocalityBinding fclb=locality.getBinding(lb, fc);
+               output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
+           } else {
+               output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
+           }
        } else {
-           
+           //yes
            output.print("((");
            if (md.getReturnType().isClass()||md.getReturnType().isArray())
                output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
@@ -1235,10 +1802,13 @@ public class BuildCode {
 
            boolean printcomma=false;
            if (GENERATEPRECISEGC) {
-               output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
+               if (state.DSM) {
+                   LocalityBinding fclb=locality.getBinding(lb, fc);
+                   output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
+               } else
+                   output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
                printcomma=true;
-           } 
-
+           }
 
            for(int i=0;i<objectparams.numPrimitives();i++) {
                TempDescriptor temp=objectparams.getPrimitive(i);
@@ -1251,7 +1821,19 @@ public class BuildCode {
                    output.print(temp.getType().getSafeSymbol());
            }
 
-           output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+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("(");
@@ -1259,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<fc.numArgs();i++) {
            Descriptor var=md.getParameter(i);
            TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
@@ -1279,7 +1873,7 @@ public class BuildCode {
                TypeDescriptor ptd=md.getParamType(i);
                if (ptd.isClass()&&!ptd.isArray())
                    output.print("(struct "+ptd.getSafeSymbol()+" *) ");
-               output.print(generateTemp(fm, targ));
+               output.print(generateTemp(fm, targ,lb));
                needcomma=true;
            }
        }
@@ -1303,17 +1897,112 @@ public class BuildCode {
        return true;
     }
 
-    private void generateFlatFieldNode(FlatMethod fm, FlatFieldNode ffn, PrintWriter output) {
-       output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ 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="";
 
@@ -1323,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[]
 
@@ -1342,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)
@@ -1455,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<objectparams.numPrimitives();i++) {
@@ -1501,7 +2302,7 @@ public class BuildCode {
        } else output.println(") {");
     }
     
-    public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
+    public void generateFlatFlagActionNode(FlatMethod fm, LocalityBinding lb, FlatFlagActionNode ffan, PrintWriter output) {
        output.println("/* FlatFlagActionNode */");
 
 
@@ -1580,9 +2381,9 @@ public class BuildCode {
                while(tagit.hasNext()) {
                    TempDescriptor tagtmp=(TempDescriptor)tagit.next();
                    if (GENERATEPRECISEGC) 
-                       output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+                       output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
                    else
-                       output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+                       output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
                }
            }
 
@@ -1592,9 +2393,9 @@ public class BuildCode {
                while(tagit.hasNext()) {
                    TempDescriptor tagtmp=(TempDescriptor)tagit.next();
                    if (GENERATEPRECISEGC)
-                       output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+                       output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
                    else
-                       output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
+                       output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
                }
            }
 
@@ -1605,103 +2406,427 @@ public class BuildCode {
                ormask=((Integer)flagortable.get(temp)).intValue();
            if (flagandtable.containsKey(temp))
                andmask=((Integer)flagandtable.get(temp)).intValue();
-           if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
-               output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
-           } else {
-               output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
-           }
+           generateFlagOrAnd(ffan, fm, lb, temp, output, ormask, andmask);
+           generateObjectDistribute(ffan, fm, lb, temp, output);
+       }
+    }
+    
+    protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp, 
+                                    PrintWriter output, int ormask, int andmask) {
+       if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
+           output.println("flagorandinit("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
+       } else {
+           output.println("flagorand("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
        }
     }
 
-     void generateOptionalArrays(PrintWriter output, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable myoptionals) {
-
-        /* SymbolTable classes = state.getClassSymbolTable();
-        for( Iterator it = classes.getAllDescriptorsIterator(); it.hasNext();){
-            ClassDescriptor cd = (ClassDescriptor)it.next();
-            output.println("Class "+cd.getSymbol());
-            Hashtable flags=(Hashtable)flagorder.get(cd);
-            for (Iterator fit = cd.getFlags(); fit.hasNext();){
-                FlagDescriptor fd = (FlagDescriptor)fit.next();
-                int flagid=1<<((Integer)flags.get(fd)).intValue();
-                output.println("\tFlag associated with "+fd.getSymbol()+" : 0x"+Integer.toHexString(flagid)+" bx"+Integer.toBinaryString(flagid));
-            }
-            }*/
+    protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp, PrintWriter output) {
+       output.println("enqueueObject("+generateTemp(fm, temp, lb)+");");
+    }
+    
+    void generateOptionalHeader(PrintWriter headers) {
+
+        //GENERATE HEADERS
+        headers.println("#include \"task.h\"\n\n");
+        headers.println("#ifndef _OPTIONAL_STRUCT_");
+        headers.println("#define _OPTIONAL_STRUCT_");
         
+        //STRUCT PREDICATEMEMBER
+        headers.println("struct predicatemember{");
+        headers.println("int type;");
+        headers.println("int numdnfterms;");
+        headers.println("int * flags;");
+        headers.println("int numtags;");
+        headers.println("int * tags;\n};\n\n");
+
+        //STRUCT OPTIONALTASKDESCRIPTOR
+        headers.println("struct optionaltaskdescriptor{");
+        headers.println("struct taskdescriptor * task;");
+        headers.println("int index;");
+        headers.println("int numenterflags;");
+        headers.println("int * enterflags;");
+        headers.println("int numpredicatemembers;");
+        headers.println("struct predicatemember ** predicatememberarray;");
+        headers.println("};\n\n");
+        
+        //STRUCT TASKFAILURE
+        headers.println("struct taskfailure {");
+        headers.println("struct taskdescriptor * task;");
+        headers.println("int index;");
+        headers.println("int numoptionaltaskdescriptors;");
+        headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
+
+        //STRUCT FSANALYSISWRAPPER
+        headers.println("struct fsanalysiswrapper{");
+        headers.println("int  flags;");
+        headers.println("int numtags;");
+        headers.println("int * tags;");
+        headers.println("int numtaskfailures;");
+        headers.println("struct taskfailure ** taskfailurearray;");
+        headers.println("int numoptionaltaskdescriptors;");
+        headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
+
+        //STRUCT CLASSANALYSISWRAPPER
+        headers.println("struct classanalysiswrapper{");
+        headers.println("int type;");
+        headers.println("int numotd;");
+        headers.println("struct optionaltaskdescriptor ** otdarray;");
+        headers.println("int numfsanalysiswrappers;");
+        headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
+        
+        headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
+
+        Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
+        while(taskit.hasNext()) {
+            TaskDescriptor td=(TaskDescriptor)taskit.next();
+            headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
+        }
+        
+    }
 
+    //CHECK OVER THIS -- THERE COULD BE SOME ERRORS HERE
+    int generateOptionalPredicate(Predicate predicate, OptionalTaskDescriptor otd, ClassDescriptor cdtemp, PrintWriter output) {
+       int predicateindex = 0;
+       //iterate through the classes concerned by the predicate
+       Set c_vard = predicate.vardescriptors;
+       Hashtable<TempDescriptor, Integer> slotnumber=new Hashtable<TempDescriptor, Integer>();
+       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<dflag.size();j++) {
+                           if (j!=0)
+                               output.println(",");
+                           Vector term=dflag.get(j);
+                           int andmask=0;
+                           int checkmask=0;
+                           for(int k=0;k<term.size();k++) {
+                               DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
+                               FlagDescriptor fd=dfa.getFlag();
+                               boolean negated=dfa.getNegated();
+                               int flagid=1<<((Integer)flags.get(fd)).intValue();
+                               andmask|=flagid;
+                               if (!negated)
+                                   checkmask|=flagid;
+                           }
+                           output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
+                       }
+                   }
+               }
+           }
+           output.println("};\n");
+           
+           //generate for tags
+           TagExpressionList tagel = predicate.tags.get(vard.getSymbol()); 
+           output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+           int numtags = 0;
+           if (tagel!=null){
+               for(int j=0;j<tagel.numTags();j++) {
+                   if (j!=0)
+                       output.println(",");
+                   TempDescriptor tmp=tagel.getTemp(j);
+                   if (!slotnumber.containsKey(tmp)) {
+                       Integer slotint=new Integer(current_slot++);
+                       slotnumber.put(tmp,slotint);
+                   }
+                   int slot=slotnumber.get(tmp).intValue();
+                   output.println("/* slot */"+ slot+", /*tagid*/"+state.getTagId(tmp.getTag()));
+               }
+               numtags = tagel.numTags();
+           }
+           output.println("};");
+           
+           //store the result into a predicatemember struct
+           output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
+           output.println("/*type*/"+typed.getClassDesc().getId()+",");
+           output.println("/* number of dnf terms */"+numberterms+",");
+           output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+           output.println("/* number of tag */"+numtags+",");
+           output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+           output.println("};\n");
+           predicateindex++;
+       }
        
-        int fscounter = 0;
-        int myocounter = 0;
-        int classescounter = 0;
+       
+       //generate an array that stores the entire predicate
+       output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
+       for( int j = 0; j<predicateindex; j++){
+           if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
+           else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
+       }
+       output.println("};\n");
+       return predicateindex;
+    }
+
+
+     void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> 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();
-            for(Iterator myoit = ((HashSet)myoptionals.get(cdtemp)).iterator(); myoit.hasNext();){
-                MyOptional myo = (MyOptional)myoit.next();
-                output.println("struct myoptional myoptional_"+"/*ID to determine*/"+"_"+"cdtemp.getsafeSymbol()"+"={");
-                //insert code to generate the myoptional
-                output.println("};");
-            }   
-            classescounter++;
+            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<numotd) maxotd = numotd; 
+            if( !c_otd.isEmpty() ){
+                for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
+                    OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
+                    
+                    //generate the int arrays for the predicate
+                    Predicate predicate = otd.predicate;
+                    int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
+                    TreeSet<Integer> fsset=new TreeSet<Integer>();
+                    //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<Integer> 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);
-            Enumeration fses = hashtbtemp.keys();
-            while(fses.hasMoreElements()){
-                //get all the possible falgstates reachable by an object
-                FlagState fs = (FlagState)fses.nextElement();
+            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 MyOptionnals
-                HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
-                //iterate through the MyOptionals
-                for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
-                    MyOptional mm = (MyOptional)mos.next();
-                    myocounter++;
-                }
-                output.println("struct myoptional * myoptionals_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
-                for(int i=0; i<myocounter; i++){
-                    if(i==myocounter-1) output.println("&myoptional_"+"/*ID to determine*/"+"_"+cdtemp.getSafeSymbol()+"};");
-                        
-                    else output.println("&myoptional_"+"/*ID to determine*/"+"_"+cdtemp.getSafeSymbol()+",");
+                
+                //get the set of OptionalTaskDescriptors corresponding
+                HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)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<OptionalTaskDescriptor> 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()+",");
                 }
-                myocounter = 0;
-                output.println("int flagstatednf_FS"+fscounter+"_"+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();
-                    //process the fs, maybe add int tagstate[]
+                    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("};");
-                output.println("struct structB structB_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
-                output.println("/* number of dnf terms (to add)*/,");
-                output.println("flagstatednf_"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
-                output.println("/* number of tags (to add)*/,");
-                output.println("tags_"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
-                output.println("/* number of myoptionals */,");
-                output.println("myoptionals_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
-                output.println("};");
+                
+                Set<TaskIndex> tiset=sa.getTaskIndex(fs);
+                for(Iterator<TaskIndex> itti=tiset.iterator();itti.hasNext();) {
+                    TaskIndex ti=itti.next();
+                    if (ti.isRuntime())
+                        continue;
+
+                    Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
+
+                    output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
+                    boolean needcomma=false;
+                    for(Iterator<OptionalTaskDescriptor> 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<TaskIndex> 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");
+                
             }
-            output.println("struct structB * structBs_"+cdtemp.getSafeSymbol()+"[] = {");
+
+            //Build the array of fsanalysiswrappers
+            output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
+            boolean needcomma=false;
             for(int i = 0; i<fscounter; i++){
-                if(i==fscounter-1) output.println("&structB_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"};");
-                        
-                    else output.println("&structB_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
+                if (needcomma) output.print(",");
+                output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
+                needcomma=true;
             }
-            fscounter = 0;
-            output.println("struct structA structA_"+cdtemp.getSafeSymbol()+"={");
-            output.println("/* class identifier */,");
-            output.println("structBs_"+cdtemp.getSafeSymbol()+"};");
+            output.println("};");
+            
+            //Build the classanalysiswrapper referring to the previous array
+            output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
+            output.println("/*type*/"+cdtemp.getId()+",");
+            output.println("/*numotd*/"+numotd+",");
+            output.println("otdarray"+cdtemp.getSafeSymbol()+",");
+            output.println("/* number of fsanalysiswrappers */"+fscounter+",");
+            output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
+            processedcd.add(cdtemp);
         }
-        output.println("struct structA * classesarray[]={");
-        e = safeexecution.keys();
-        int j = 0;
-        while (e.hasMoreElements()) {
-            ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
-            j++;
-            if(j==classescounter) output.println("&structA_"+cdtemp.getSafeSymbol()+"};");
-            else output.println("&structA_"+cdtemp.getSafeSymbol()+",");
+        
+        //build an array containing every classes for which code has been build
+        output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
+        for(int i=0;i<state.numClasses();i++) {
+            ClassDescriptor cn=cdarray[i];
+            if (i>0)
+                output.print(", ");
+            if (processedcd.contains(cn))
+                output.print("&classanalysiswrapper_"+cn.getSafeSymbol());
+            else
+                output.print("NULL");
         }
-        output.println("int numclasses = "+classescounter+";");
+        output.println("};");
         
+        output.println("#define MAXOTD "+maxotd);
+        headers.println("#endif");
      }
+
+    public List<OptionalTaskDescriptor> ordertd(Set<OptionalTaskDescriptor> otdset) {
+       Relation r=new Relation();
+       for(Iterator<OptionalTaskDescriptor>otdit=otdset.iterator();otdit.hasNext();) {
+           OptionalTaskDescriptor otd=otdit.next();
+           TaskIndex ti=new TaskIndex(otd.td, otd.getIndex());
+           r.put(ti, otd);
+       }
+
+       LinkedList<OptionalTaskDescriptor> l=new LinkedList<OptionalTaskDescriptor>();
+       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) {
+    }
 }