X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FIR%2FFlat%2FBuildCode.java;h=e14ff60a4c7b607e712de8ad4eb04b34c11e83e2;hb=b37615d9a26fc6aeddd64d941494d3774282bcce;hp=17408edc5a361b4e3c277663e1c7d49ef999ff7c;hpb=6bd44ebe9bdaf3982470ad744f4bf6a356639cce;p=IRC.git diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 17408edc..e14ff60a 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -6,6 +6,7 @@ import IR.Tree.DNFFlagAtom; import IR.Tree.TagExpressionList; import IR.Tree.OffsetNode; import IR.*; + import java.util.*; import java.io.*; @@ -23,7 +24,10 @@ import Analysis.Locality.DCWrapper; import Analysis.Locality.DelayComputation; import Analysis.Locality.BranchAnalysis; import Analysis.CallGraph.CallGraph; +import Analysis.Disjoint.AllocSite; +import Analysis.Disjoint.Effect; import Analysis.Disjoint.ReachGraph; +import Analysis.Disjoint.Taint; import Analysis.OoOJava.OoOJavaAnalysis; import Analysis.Prefetch.*; import Analysis.Loops.WriteBarrier; @@ -74,10 +78,12 @@ public class BuildCode { PrefetchAnalysis pa; MLPAnalysis mlpa; OoOJavaAnalysis oooa; + String maxTaskRecSizeStr="__maxTaskRecSize___"; String mlperrstr = "if(status != 0) { "+ "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+ "perror(errmsg); exit(-1); }"; boolean nonSESEpass=true; + RuntimeConflictResolver rcr = null; WriteBarrier wb; DiscoverConflicts dc; DiscoverConflicts recorddc; @@ -153,6 +159,7 @@ public class BuildCode { PrintWriter outtaskdefs=null; PrintWriter outoptionalarrays=null; PrintWriter optionalheaders=null; + PrintWriter outglobaldefs=null; try { if (state.SANDBOX) { @@ -161,6 +168,10 @@ public class BuildCode { 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); + if(state.MGC) { + // TODO add version for normal Java later + outglobaldefs=new PrintWriter(new FileOutputStream(PREFIX+"globaldefs.h"), true); + } outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true); outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true); if (state.TASK) { @@ -182,6 +193,9 @@ public class BuildCode { /* Build the virtual dispatch tables */ buildVirtualTables(outvirtual); + /* Tag the methods that are invoked by static blocks */ + tagMethodInvokedByStaticBlock(); + /* Output includes */ outmethodheader.println("#ifndef METHODHEADERS_H"); outmethodheader.println("#define METHODHEADERS_H"); @@ -209,6 +223,14 @@ public class BuildCode { outmethodheader.println("#include "); outmethodheader.println("#include \"mlp_runtime.h\""); outmethodheader.println("#include \"psemaphore.h\""); + outmethodheader.println("#include \"memPool.h\""); + + if (state.RCR) + outmethodheader.println("#include \"rcr_runtime.h\""); + + // spit out a global to inform all worker threads with + // the maximum size is for any task record + outmethodheader.println("extern int "+maxTaskRecSizeStr+";"); } /* Output Structures */ @@ -216,15 +238,36 @@ public class BuildCode { // Output the C class declarations // These could mutually reference each other - outputClassDeclarations(outclassdefs); + + if(state.MGC) { + // TODO add version for normal Java later + outglobaldefs.println("#ifndef __GLOBALDEF_H_"); + outglobaldefs.println("#define __GLOBALDEF_H_"); + outglobaldefs.println(""); + outglobaldefs.println("struct global_defs_t {"); + } + + outclassdefs.println("#ifndef __CLASSDEF_H_"); + outclassdefs.println("#define __CLASSDEF_H_"); + outputClassDeclarations(outclassdefs, outglobaldefs); // Output function prototypes and structures for parameters Iterator it=state.getClassSymbolTable().getDescriptorsIterator(); while(it.hasNext()) { ClassDescriptor cn=(ClassDescriptor)it.next(); - generateCallStructs(cn, outclassdefs, outstructs, outmethodheader); + generateCallStructs(cn, outclassdefs, outstructs, outmethodheader, outglobaldefs); } + outclassdefs.println("#endif"); outclassdefs.close(); + if(state.MGC) { + // TODO add version for normal Java later + outglobaldefs.println("};"); + outglobaldefs.println(""); + outglobaldefs.println("extern struct global_defs_t * global_defs_p;"); + outglobaldefs.println("#endif"); + outglobaldefs.flush(); + outglobaldefs.close(); + } if (state.TASK) { /* Map flags to integers */ @@ -242,7 +285,7 @@ public class BuildCode { outputTaskTypes(outtask); } - if( state.MLP || state.OOOJAVA) { + if( state.MLP || state.OOOJAVA) { // have to initialize some SESE compiler data before // analyzing normal methods, which must happen before // generating SESE internal code @@ -253,18 +296,22 @@ public class BuildCode { }else{ seseit=oooa.getAllSESEs().iterator(); } + + //TODO signal the object that will report errors + if(state.RCR) { + try { + rcr = new RuntimeConflictResolver(PREFIX, oooa); + rcr.setGlobalEffects(oooa.getDisjointAnalysis().getEffectsAnalysis().getAllEffects()); + } catch (FileNotFoundException e) { + System.out.println("Runtime Conflict Resolver could not create output file."); + } + rcr.init(); + } + while(seseit.hasNext()){ FlatSESEEnterNode fsen = seseit.next(); initializeSESE( fsen ); - - // invoke rcr - if(state.RCR){ -// FlatMethod fm=fsen.getfmEnclosing(); -// ReachGraph rg=oooa.getDisjointAnalysis().getReachGraph(fm.getMethod()); - } - } - } /* Build the actual methods */ @@ -273,6 +320,10 @@ public class BuildCode { // Output function prototypes and structures for SESE's and code if( state.MLP || state.OOOJAVA ) { + // spit out a global to inform all worker threads with + // the maximum size is for any task record + outmethod.println("int "+maxTaskRecSizeStr+" = 0;"); + // used to differentiate, during code generation, whether we are // passing over SESE body code, or non-SESE code nonSESEpass = false; @@ -324,21 +375,110 @@ public class BuildCode { outmethod.close(); outstructs.println("#endif"); outstructs.close(); + if(rcr != null) { + rcr.close(); + System.out.println("Runtime Conflict Resolver Done."); + } + } + + /* This method goes though the call graph and tag those methods that are + * invoked inside static blocks + */ + protected void tagMethodInvokedByStaticBlock() { + if(state.MGC) { + Iterator it_sclasses = this.state.getSClassSymbolTable().getDescriptorsIterator(); + MethodDescriptor current_md=null; + HashSet tovisit=new HashSet(); + HashSet visited=new HashSet(); + + while(it_sclasses.hasNext()) { + ClassDescriptor cd = (ClassDescriptor)it_sclasses.next(); + MethodDescriptor md = (MethodDescriptor)cd.getMethodTable().get("staticblocks"); + tovisit.add(md); + } + + while(!tovisit.isEmpty()) { + current_md=(MethodDescriptor)tovisit.iterator().next(); + tovisit.remove(current_md); + visited.add(current_md); + Iterator it_callee = this.callgraph.getCalleeSet(current_md).iterator(); + while(it_callee.hasNext()) { + Descriptor d = (Descriptor)it_callee.next(); + if(d instanceof MethodDescriptor) { + if(!visited.contains(d)) { + ((MethodDescriptor)d).setIsInvokedByStatic(true); + tovisit.add(d); + } + } + } + } + } // TODO for normal Java version + } + + /* This code generates code for each static block and static field + * initialization.*/ + protected void outputStaticBlocks(PrintWriter outmethod) { + // execute all the static blocks and all the static field initializations + // TODO } + /* This code generates code to create a Class object for each class for + * getClass() method. + * */ + protected void outputClassObjects(PrintWriter outmethod) { + // for each class, initialize its Class object + if(state.MGC) { + SymbolTable ctbl = this.state.getClassSymbolTable(); + Iterator it_classes = ctbl.getDescriptorsIterator(); + while(it_classes.hasNext()) { + ClassDescriptor t_cd = (ClassDescriptor)it_classes.next(); + outmethod.println(" {"); + outmethod.println(" global_defs_p->"+t_cd.getSafeSymbol()+"classobj.type="+t_cd.getId()+";"); + outmethod.println(" initlock((struct ___Object___ *)(&(global_defs_p->"+t_cd.getSafeSymbol()+"classobj)));"); + outmethod.println(" }"); + } + } // else TODO normal java version + } /* 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) { + protected void outputMainMethod(PrintWriter outmethod) { outmethod.println("int main(int argc, const char *argv[]) {"); outmethod.println(" int i;"); + + outputStaticBlocks(outmethod); + outputClassObjects(outmethod); if (state.MLP || state.OOOJAVA) { - //outmethod.println(" pthread_once( &mlpOnceObj, mlpInitOncePerThread );"); + + // do a calculation to determine which task record + // is the largest, store that as a global value for + // allocating records + Iterator seseit; + if(state.MLP){ + seseit=mlpa.getAllSESEs().iterator(); + }else{ + seseit=oooa.getAllSESEs().iterator(); + } + while(seseit.hasNext()){ + FlatSESEEnterNode fsen = seseit.next(); + outmethod.println("if( sizeof( "+fsen.getSESErecordName()+ + " ) > "+maxTaskRecSizeStr+ + " ) { "+maxTaskRecSizeStr+ + " = sizeof( "+fsen.getSESErecordName()+ + " ); }" ); + } + + outmethod.println(" runningSESE = NULL;"); outmethod.println(" workScheduleInit( "+state.MLP_NUMCORES+", invokeSESEmethod );"); + + //initializes data structures needed for the RCR traverser + if(state.RCR && rcr != null) { + outmethod.println(" initializeStructsRCR();"); + } } if (state.DSM) { @@ -504,6 +644,11 @@ public class BuildCode { outmethod.println("#include \"methodheaders.h\""); outmethod.println("#include \"virtualtable.h\""); outmethod.println("#include \"runtime.h\""); + + // always include: compiler directives will leave out + // instrumentation when option is not set + outmethod.println("#include \"coreprof/coreprof.h\""); + if (state.SANDBOX) { outmethod.println("#include \"sandboxdefs.c\""); } @@ -515,12 +660,18 @@ public class BuildCode { outmethod.println("#include \"localobjects.h\""); } if(state.MULTICORE) { - outmethod.println("#include \"task.h\""); + if(state.TASK) { + outmethod.println("#include \"task.h\""); + } outmethod.println("#include \"multicoreruntime.h\""); outmethod.println("#include \"runtime_arch.h\""); } - if (state.THREAD||state.DSM||state.SINGLETM) + if (state.THREAD||state.DSM||state.SINGLETM) { outmethod.println("#include "); + } + if(state.MGC) { + outmethod.println("#include \"thread.h\""); + } if (state.main!=null) { outmethod.println("#include "); } @@ -532,11 +683,18 @@ public class BuildCode { outmethod.println("#include "); outmethod.println("#include \"mlp_runtime.h\""); outmethod.println("#include \"psemaphore.h\""); - } - if (state.COREPROF) { - outmethod.println("#include \"coreprof.h\""); + + if( state.RCR ) { + outmethod.println("#include \"trqueue.h\""); + outmethod.println("#include \"RuntimeConflictResolver.h\""); + outmethod.println("#include \"rcr_runtime.h\""); + } } + if(state.MGC) { + // TODO add version for normal Java later + outmethod.println("struct global_defs_t * global_defs_p;"); + } //Store the sizes of classes & array elements generateSizeArray(outmethod); @@ -590,6 +748,10 @@ public class BuildCode { outstructs.println("#include \"mlp_runtime.h\""); outstructs.println("#include \"psemaphore.h\""); } + if (state.RCR) { + outstructs.println("#include \"rcr_runtime.h\""); + } + /* Output #defines that the runtime uses to determine type * numbers for various objects it needs */ @@ -644,7 +806,7 @@ public class BuildCode { } } - protected void outputClassDeclarations(PrintWriter outclassdefs) { + protected void outputClassDeclarations(PrintWriter outclassdefs, PrintWriter outglobaldefs) { if (state.THREAD||state.DSM||state.SINGLETM) outclassdefs.println("#include "); outclassdefs.println("#ifndef INTPTR"); @@ -662,6 +824,19 @@ public class BuildCode { while(it.hasNext()) { ClassDescriptor cn=(ClassDescriptor)it.next(); outclassdefs.println("struct "+cn.getSafeSymbol()+";"); + + if(state.MGC) { + // TODO add version for normal Java later + if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { + // this class has static fields/blocks, need to add a global flag to + // indicate if its static fields have been initialized and/or if its + // static blocks have been executed + outglobaldefs.println(" int "+cn.getSafeSymbol()+"static_block_exe_flag;"); + } + + // for each class, create a global object + outglobaldefs.println(" struct Class "+cn.getSafeSymbol()+"classobj;"); + } } outclassdefs.println(""); //Print out definition for array type @@ -669,6 +844,7 @@ public class BuildCode { outclassdefs.println(" int type;"); if(state.MLP || state.OOOJAVA ){ outclassdefs.println(" int oid;"); + outclassdefs.println(" int allocsite;"); } if (state.EVENTMONITOR) { outclassdefs.println(" int objuid;"); @@ -678,6 +854,13 @@ public class BuildCode { outclassdefs.println(" void * lockentry;"); outclassdefs.println(" int lockcount;"); } + if(state.MGC) { + outclassdefs.println(" int mutex;"); + outclassdefs.println(" int objlock;"); + if(state.MULTICOREGC) { + outclassdefs.println(" int marked;"); + } + } if (state.TASK) { outclassdefs.println(" int flag;"); if(!state.MULTICORE) { @@ -696,7 +879,7 @@ public class BuildCode { outclassdefs.println(" int * fses;"); } } - printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs); + printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs); if (state.STMARRAY) { outclassdefs.println(" int lowindex;"); @@ -710,10 +893,64 @@ public class BuildCode { outclassdefs.println(" int ___length___;"); outclassdefs.println("};\n"); + + if(state.MGC) { + // TODO add version for normal Java later + outclassdefs.println(""); + //Print out definition for Class type + outclassdefs.println("struct Class {"); + outclassdefs.println(" int type;"); + if(state.MLP || state.OOOJAVA ){ + outclassdefs.println(" int oid;"); + outclassdefs.println(" int allocsite;"); + } + if (state.EVENTMONITOR) { + outclassdefs.println(" int objuid;"); + } + if (state.THREAD) { + outclassdefs.println(" pthread_t tid;"); + outclassdefs.println(" void * lockentry;"); + outclassdefs.println(" int lockcount;"); + } + if(state.MGC) { + outclassdefs.println(" int mutex;"); + outclassdefs.println(" int objlock;"); + if(state.MULTICOREGC) { + outclassdefs.println(" int marked;"); + } + } + if (state.TASK) { + outclassdefs.println(" int flag;"); + if(!state.MULTICORE) { + outclassdefs.println(" void * flagptr;"); + } else { + outclassdefs.println(" int version;"); + outclassdefs.println(" int * lock;"); // lock entry for this obj + outclassdefs.println(" int mutex;"); + outclassdefs.println(" int lockcount;"); + if(state.MULTICOREGC) { + outclassdefs.println(" int marked;"); + } + } + if(state.OPTIONAL) { + outclassdefs.println(" int numfses;"); + outclassdefs.println(" int * fses;"); + } + } + printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs, outglobaldefs); + outclassdefs.println("};\n"); + } + + outclassdefs.println(""); outclassdefs.println("extern int classsize[];"); outclassdefs.println("extern int hasflags[];"); outclassdefs.println("extern unsigned INTPTR * pointerarray[];"); outclassdefs.println("extern int supertypes[];"); + if(state.MGC) { + // TODO add version for normal Java later + outclassdefs.println("#include \"globaldefs.h\""); + } + outclassdefs.println(""); } /** Prints out definitions for generic task structures */ @@ -1343,11 +1580,11 @@ public class BuildCode { /** Force consistent field ordering between inherited classes. */ - private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) { + private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout, PrintWriter globaldefout) { ClassDescriptor sp=cn.getSuperDesc(); if (sp!=null) - printClassStruct(sp, classdefout); + printClassStruct(sp, classdefout, globaldefout); if (!fieldorder.containsKey(cn)) { Vector fields=new Vector(); @@ -1365,7 +1602,12 @@ public class BuildCode { FieldDescriptor fd=(FieldDescriptor)fields.get(i); if (fd.getType().isClass()||fd.getType().isArray()) classdefout.println(" struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";"); - else + else if ((state.MGC) && (fd.isStatic())) { + // TODO add version for normal Java later + // static field + globaldefout.println(" "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";"); + classdefout.println(" "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";"); + } else classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";"); } } @@ -1408,12 +1650,13 @@ public class BuildCode { * passed in (when PRECISE GC is enabled) and (2) function * prototypes for the methods */ - protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) { + protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout, PrintWriter globaldefout) { /* Output class structure */ classdefout.println("struct "+cn.getSafeSymbol()+" {"); classdefout.println(" int type;"); if(state.MLP || state.OOOJAVA){ classdefout.println(" int oid;"); + classdefout.println(" int allocsite;"); } if (state.EVENTMONITOR) { classdefout.println(" int objuid;"); @@ -1423,7 +1666,13 @@ public class BuildCode { classdefout.println(" void * lockentry;"); classdefout.println(" int lockcount;"); } - + if(state.MGC) { + classdefout.println(" int mutex;"); + classdefout.println(" int objlock;"); + if(state.MULTICOREGC) { + classdefout.println(" int marked;"); + } + } if (state.TASK) { classdefout.println(" int flag;"); if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) { @@ -1442,7 +1691,7 @@ public class BuildCode { classdefout.println(" int * fses;"); } } - printClassStruct(cn, classdefout); + printClassStruct(cn, classdefout, globaldefout); classdefout.println("};\n"); if (state.DSM||state.SINGLETM) { @@ -1800,7 +2049,7 @@ public class BuildCode { Iterator pItr = callerSESEplaceholder.getNeededStaticNames().iterator(); while( pItr.hasNext() ) { SESEandAgePair pair = pItr.next(); - output.println(" void* "+pair+";"); + output.println(" void* "+pair+" = NULL;"); } // declare variables for tracking dynamic sources @@ -1808,8 +2057,8 @@ public class BuildCode { Iterator dynSrcItr = callerSESEplaceholder.getDynamicVarSet().iterator(); while( dynSrcItr.hasNext() ) { TempDescriptor dynSrcVar = dynSrcItr.next(); - output.println(" void* "+dynSrcVar+"_srcSESE;"); - output.println(" int "+dynSrcVar+"_srcOffset;"); + output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;"); + output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;"); } } } @@ -1835,10 +2084,8 @@ public class BuildCode { System.out.println("size="+lockSet.size()); if (lockSet.size() > 0) { output.println(" numMemoryQueue=" + lockSet.size() + ";"); - output - .println(" seseCaller->numMemoryQueue=numMemoryQueue;"); - output - .println(" seseCaller->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); + output.println(" runningSESE->numMemoryQueue=numMemoryQueue;"); + output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); output.println(); } } @@ -1861,17 +2108,15 @@ public class BuildCode { System.out.println("size="+lockSet.size()); if (lockSet.size() > 0) { output.println(" numMemoryQueue=" + lockSet.size() + ";"); - output - .println(" seseCaller->numMemoryQueue=numMemoryQueue;"); - output - .println(" seseCaller->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); + output.println(" runningSESE->numMemoryQueue=numMemoryQueue;"); + output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); output.println(); } } } } - } + } /* Check to see if we need to do a GC if this is a @@ -1890,6 +2135,31 @@ public class BuildCode { } } } + + if(state.MGC) { + // TODO add version for normal Java later + if(fm.getMethod().isStaticBlock()) { + // a static block, check if it has been executed + output.println(" if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag != 0) {"); + output.println(" return;"); + output.println(" }"); + output.println(""); + } + if((!fm.getMethod().isStaticBlock()) && (fm.getMethod().getReturnType() == null) && (cn != null)){ + // is a constructor, check and output initialization of the static fields + // here does not initialize the static fields of the class, instead it + // redirect the corresponding fields in the object to the global_defs_p + Vector fields=(Vector)fieldorder.get(cn); + + for(int i=0; i"+fd.getSafeSymbol()+"=&(global_defs_p->"+cn.getSafeSymbol()+fd.getSafeSymbol()+");"); + } + } + } + } generateCode(fm.getNext(0), fm, lb, null, output, true); @@ -1957,6 +2227,18 @@ public class BuildCode { } } + // used when generating the specific SESE record struct + // to remember the FIRST field name of sese records + // that the current SESE depends on--we need to know the + // offset to the first one for garbage collection + protected void addingDepRecField( FlatSESEEnterNode fsen, + String field ) { + if( fsen.getFirstDepRecField() == null ) { + fsen.setFirstDepRecField( field ); + } + fsen.incNumDepRecs(); + } + protected void generateMethodSESE(FlatSESEEnterNode fsen, LocalityBinding lb, PrintWriter outputStructs, @@ -1988,6 +2270,27 @@ public class BuildCode { outputStructs.println("};\n"); + // divide in-set and out-set into objects and primitives to prep + // for the record generation just below + Set inSetAndOutSet = new HashSet(); + inSetAndOutSet.addAll( fsen.getInVarSet() ); + inSetAndOutSet.addAll( fsen.getOutVarSet() ); + + Set inSetAndOutSetObjs = new HashSet(); + Set inSetAndOutSetPrims = new HashSet(); + + Iterator itr = inSetAndOutSet.iterator(); + while( itr.hasNext() ) { + TempDescriptor temp = itr.next(); + TypeDescriptor type = temp.getType(); + if( type.isPtr() ) { + inSetAndOutSetObjs.add( temp ); + } else { + inSetAndOutSetPrims.add( temp ); + } + } + + // generate the SESE record structure outputStructs.println(fsen.getSESErecordName()+" {"); @@ -1997,82 +2300,85 @@ public class BuildCode { outputStructs.println(" SESEcommon common;"); // then garbage list stuff + outputStructs.println(" /* next is in-set and out-set objects that look like a garbage list */"); outputStructs.println(" int size;"); outputStructs.println(" void * next;"); - // DYNAMIC stuff was here - - // invar source taking was here - - // space for all in and out set primitives - Set inSetAndOutSet = new HashSet(); - inSetAndOutSet.addAll( fsen.getInVarSet() ); - inSetAndOutSet.addAll( fsen.getOutVarSet() ); + // I think that the set of TempDescriptors inSetAndOutSetObjs + // calculated above should match the pointer object params + // used in the following code, but let's just leave the working + // implementation unless there is actually a problem... - Set inSetAndOutSetPrims = new HashSet(); + Vector inset=fsen.getInVarsForDynamicCoarseConflictResolution(); + for(int i=0; i itr = inSetAndOutSet.iterator(); - while( itr.hasNext() ) { - TempDescriptor temp = itr.next(); - TypeDescriptor type = temp.getType(); - if( !type.isPtr() ) { - inSetAndOutSetPrims.add( temp ); + for(int i=0; i itrPrims = inSetAndOutSetPrims.iterator(); while( itrPrims.hasNext() ) { TempDescriptor temp = itrPrims.next(); TypeDescriptor type = temp.getType(); - if(!type.isPrimitive()){ - outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+";"); + if(type.isPrimitive()){ + outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+"; /* in-set or out-set primitive */"); } } - - for(int i=0; i itrDynInVars = fsen.getDynamicInVarSet().iterator(); while( itrDynInVars.hasNext() ) { TempDescriptor dynInVar = itrDynInVars.next(); -// outputStructs.println(" void* "+dynInVar+"_srcSESE;"); - outputStructs.println(" int "+dynInVar+"_srcOffset;"); + outputStructs.println(" INTPTR "+dynInVar+"_srcOffset; /* dynamic tracking primitive */"); } - itrPrims = inSetAndOutSetPrims.iterator(); - while( itrPrims.hasNext() ) { - TempDescriptor temp = itrPrims.next(); - TypeDescriptor type = temp.getType(); - if(type.isPrimitive()){ - outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+";"); - } - } - - outputStructs.println(" int prevSESECount;"); - // DYNAMIC stuff needs a source SESE ptr and offset + outputStructs.println(" /* everything after this should be pointers to an SESE record */" ); + + // other half of info for dynamic tracking, the SESE record pointer itrDynInVars = fsen.getDynamicInVarSet().iterator(); while( itrDynInVars.hasNext() ) { TempDescriptor dynInVar = itrDynInVars.next(); - outputStructs.println(" void* "+dynInVar+"_srcSESE;"); -// outputStructs.println(" int "+dynInVar+"_srcOffset;"); + String depRecField = dynInVar+"_srcSESE"; + outputStructs.println(" SESEcommon* "+depRecField+";"); + addingDepRecField( fsen, depRecField ); } - // in-set source tracking - // in-vars that are READY come from parent, don't need anything - // stuff STATIC needs a custom SESE pointer for each age pair + // statically known sese sources are record pointers, too Iterator itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator(); while( itrStaticInVarSrcs.hasNext() ) { SESEandAgePair srcPair = itrStaticInVarSrcs.next(); outputStructs.println(" "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";"); - } + addingDepRecField(fsen, srcPair.toString()); + } + + if (state.RCR) { + if (inset.size()!=0) + outputStructs.println("struct rcrRecord rcrRecords["+inset.size()+"];"); + } + if( fsen.getFirstDepRecField() != null ) { + outputStructs.println(" /* compiler believes first dependent SESE record field above is: "+ + fsen.getFirstDepRecField()+" */" ); + } outputStructs.println("};\n"); @@ -2104,6 +2410,7 @@ public class BuildCode { output.print(fsen.getSESErecordName()+"* "+paramsprefix); output.println("){\n"); + TempObject objecttemp=(TempObject) tempstable.get(md); if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { @@ -2133,7 +2440,7 @@ public class BuildCode { Iterator pItr = fsen.getNeededStaticNames().iterator(); while( pItr.hasNext() ) { SESEandAgePair pair = pItr.next(); - output.println(" void* "+pair+";"); + output.println(" SESEcommon* "+pair+" = NULL;"); } // declare variables for tracking dynamic sources @@ -2141,8 +2448,8 @@ public class BuildCode { Iterator dynSrcItr = fsen.getDynamicVarSet().iterator(); while( dynSrcItr.hasNext() ) { TempDescriptor dynSrcVar = dynSrcItr.next(); - output.println(" void* "+dynSrcVar+"_srcSESE;"); - output.println(" int "+dynSrcVar+"_srcOffset;"); + output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;"); + output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;"); } // declare local temps for in-set primitives, and if it is @@ -2171,32 +2478,36 @@ public class BuildCode { if( !type.isPtr() && !fsen.getInVarSet().contains( temp ) ) { output.println(" "+type+" "+temp+";"); } - } + } + + + // initialize thread-local var to a the task's record, which is fused + // with the param list + output.println(" "); + output.println(" // code of this task's body should use this to access the running task record"); + output.println(" runningSESE = &(___params___->common);"); + output.println(" "); // setup memory queue // eom if(state.OOOJAVA){ - output.println(" // set up memory queues "); - output.println(" int numMemoryQueue=0;"); - output.println(" int memoryQueueItemID=0;"); - Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(fsen); - if (graph != null && graph.hasConflictEdge()) { - output.println(" {"); - output - .println(" SESEcommon* parentCommon = &(___params___->common);"); - Set lockSet = oooa.getLockMappings(graph); - System.out.println("#lockSet="+lockSet); - if (lockSet.size() > 0) { - output.println(" numMemoryQueue=" + lockSet.size() + ";"); - output - .println(" parentCommon->numMemoryQueue=numMemoryQueue;"); - output - .println(" parentCommon->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); - output.println(); - } - output.println(" }"); + output.println(" // set up memory queues "); + output.println(" int numMemoryQueue=0;"); + output.println(" int memoryQueueItemID=0;"); + Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(fsen); + if (graph != null && graph.hasConflictEdge()) { + output.println(" {"); + Set lockSet = oooa.getLockMappings(graph); + System.out.println("#lockSet="+lockSet); + if (lockSet.size() > 0) { + output.println(" numMemoryQueue=" + lockSet.size() + ";"); + output.println(" runningSESE->numMemoryQueue=numMemoryQueue;"); + output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); + output.println(); } - }else{ + output.println(" }"); + } + } else { output.println(" // set up memory queues "); output.println(" int numMemoryQueue=0;"); output.println(" int memoryQueueItemID=0;"); @@ -2204,56 +2515,63 @@ public class BuildCode { graph = mlpa.getConflictGraphResults().get(fsen); if (graph != null && graph.hasConflictEdge()) { output.println(" {"); - output - .println(" SESEcommon* parentCommon = &(___params___->common);"); HashSet lockSet = mlpa.getConflictGraphLockMap().get( graph); System.out.println("#lockSet="+lockSet); if (lockSet.size() > 0) { output.println(" numMemoryQueue=" + lockSet.size() + "; "); - output - .println(" parentCommon->numMemoryQueue=numMemoryQueue;"); - output - .println(" parentCommon->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); + output.println(" runningSESE->numMemoryQueue=numMemoryQueue;"); + output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);"); output.println(); } output.println(" }"); } - } + // set up a task's mem pool to recycle the allocation of children tasks + // don't bother if the task never has children (a leaf task) + output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" ); + if( !fsen.getIsLeafSESE() ) { + output.println(" runningSESE->taskRecordMemPool = poolcreate( "+ + maxTaskRecSizeStr+" );"); + } else { + // make it clear we purposefully did not initialize this + output.println(" runningSESE->taskRecordMemPool = (MemPool*)0x1;"); + } + output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" ); + + // copy in-set into place, ready vars were already // copied when the SESE was issued Iterator tempItr; // static vars are from a known SESE + output.println(" // copy variables from static sources"); tempItr = fsen.getStaticInVarSet().iterator(); while( tempItr.hasNext() ) { TempDescriptor temp = tempItr.next(); VariableSourceToken vst = fsen.getStaticInVarSrc( temp ); SESEandAgePair srcPair = new SESEandAgePair( vst.getSESE(), vst.getAge() ); - - // can't grab something from this source until it is done - output.println(" {"); - /* - If we are running, everything is done. This check is redundant. - - output.println(" SESEcommon* com = (SESEcommon*)"+paramsprefix+"->"+srcPair+";" ); - output.println(" pthread_mutex_lock( &(com->lock) );"); - output.println(" while( com->doneExecuting == FALSE ) {"); - output.println(" pthread_cond_wait( &(com->doneCond), &(com->lock) );"); - output.println(" }"); - output.println(" pthread_mutex_unlock( &(com->lock) );"); - */ - output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+ + output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+ " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";"); - + } + + output.println(" // decrement references to static sources"); + for( Iterator pairItr = fsen.getStaticInVarSrcs().iterator(); pairItr.hasNext(); ) { + SESEandAgePair srcPair = pairItr.next(); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" {"); + output.println(" SESEcommon* src = &("+paramsprefix+"->"+srcPair+"->common);"); + output.println(" RELEASE_REFERENCE_TO( src );"); output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); } + // dynamic vars come from an SESE and src + output.println(" // copy variables from dynamic sources"); tempItr = fsen.getDynamicInVarSet().iterator(); while( tempItr.hasNext() ) { TempDescriptor temp = tempItr.next(); @@ -2262,17 +2580,6 @@ public class BuildCode { // go grab it from the SESE source output.println(" if( "+paramsprefix+"->"+temp+"_srcSESE != NULL ) {"); - // gotta wait until the source is done - output.println(" SESEcommon* com = (SESEcommon*)"+paramsprefix+"->"+temp+"_srcSESE;" ); - /* - If we are running, everything is done! - output.println(" pthread_mutex_lock( &(com->lock) );"); - output.println(" while( com->doneExecuting == FALSE ) {"); - output.println(" pthread_cond_wait( &(com->doneCond), &(com->lock) );"); - output.println(" }"); - output.println(" pthread_mutex_unlock( &(com->lock) );"); - */ - String typeStr; if( type.isNull() ) { typeStr = "void*"; @@ -2283,11 +2590,16 @@ public class BuildCode { } output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+ - " = *(("+typeStr+"*) ("+ + " = *(("+typeStr+"*) ((void*)"+ paramsprefix+"->"+temp+"_srcSESE + "+ paramsprefix+"->"+temp+"_srcOffset));"); - // or if the source was our parent, its in the record to grab + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" SESEcommon* src = "+paramsprefix+"->"+temp+"_srcSESE;"); + output.println(" RELEASE_REFERENCE_TO( src );"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + + // or if the source was our parent, its already in our record to grab output.println(" } else {"); output.println(" "+generateTemp( fsen.getfmBogus(), temp, null )+ " = "+paramsprefix+"->"+temp+";"); @@ -2308,8 +2620,12 @@ public class BuildCode { // } } - // initialize thread-local var to a non-zero, invalid address - output.println(" seseCaller = (SESEcommon*) 0x2;"); + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKEXECUTE"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + HashSet exitset=new HashSet(); exitset.add(seseExit); generateCode(fsen.getNext(0), fm, null, exitset, output, true); @@ -2353,10 +2669,9 @@ public class BuildCode { (state.OOOJAVA && fsen.equals( oooa.getMainSESE() )) ) { outmethod.println( " /* work scheduler works forever, explicitly exit */"); - if (state.COREPROF) { - outmethod.println("EXITPROFILER();"); - outmethod.println("DUMPPROFILER();"); - } + outmethod.println( " CP_EXIT();"); + outmethod.println( " CP_DUMP();"); + outmethod.println( " workScheduleExit();"); outmethod.println( " exit( 0 );"); } @@ -2378,8 +2693,9 @@ public class BuildCode { protected void generateCode(FlatNode first, FlatMethod fm, LocalityBinding lb, - Set stopset, - PrintWriter output, boolean firstpass) { + Set stopset, + PrintWriter output, + boolean firstpass) { /* Assign labels to FlatNode's if necessary.*/ @@ -2467,6 +2783,14 @@ public class BuildCode { assert fsxn.getFlatEnter().equals( fsen ); } if (current_node.kind()!=FKind.FlatReturnNode) { + if(state.MGC) { + // TODO add version for normal Java later + if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) { + // a static block, check if it has been executed + output.println(" global_defs_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;"); + output.println(""); + } + } output.println(" return;"); } current_node=null; @@ -2766,7 +3090,7 @@ public class BuildCode { cp = oooa.getCodePlan(fn); } - if( cp != null ) { + if( cp != null ) { FlatSESEEnterNode currentSESE = cp.getCurrentSESE(); @@ -2780,18 +3104,28 @@ public class BuildCode { SESEandAgePair pair = new SESEandAgePair( vst.getSESE(), vst.getAge() ); output.println(" {"); - output.println(" SESEcommon* common = (SESEcommon*) "+pair+";"); + output.println(" "+pair.getSESE().getSESErecordName()+"* child = ("+ + pair.getSESE().getSESErecordName()+"*) "+pair+";"); - output.println(" pthread_mutex_lock( &(common->lock) );"); - output.println(" while( common->doneExecuting == FALSE ) {"); - output.println(" pthread_cond_wait( &(common->doneCond), &(common->lock) );"); + output.println(" SESEcommon* childCom = (SESEcommon*) "+pair+";"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + output.println(" pthread_mutex_lock( &(childCom->lock) );"); + output.println(" if( childCom->doneExecuting == FALSE ) {"); + output.println(" psem_reset( &runningSESEstallSem );"); + output.println(" childCom->parentsStallSem = &runningSESEstallSem;"); + output.println(" pthread_mutex_unlock( &(childCom->lock) );"); + output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); + output.println(" } else {"); + output.println(" pthread_mutex_unlock( &(childCom->lock) );"); output.println(" }"); - output.println(" pthread_mutex_unlock( &(common->lock) );"); - // copy things we might have stalled for - output.println(" "+pair.getSESE().getSESErecordName()+"* child = ("+ - pair.getSESE().getSESErecordName()+"*) "+pair+";"); - + // copy things we might have stalled for Iterator tdItr = cp.getCopySet( vst ).iterator(); while( tdItr.hasNext() ) { TempDescriptor td = tdItr.next(); @@ -2805,9 +3139,15 @@ public class BuildCode { " = child->"+vst.getAddrVar().getSafeSymbol()+";"); } + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + output.println(" }"); } - + // for each variable with a dynamic source, stall just for that variable Iterator dynItr = cp.getDynamicStallSet().iterator(); while( dynItr.hasNext() ) { @@ -2817,8 +3157,24 @@ public class BuildCode { // otherwise the dynamic write nodes will have the local var up-to-date output.println(" {"); output.println(" if( "+dynVar+"_srcSESE != NULL ) {"); - output.println(" SESEcommon* common = (SESEcommon*) "+dynVar+"_srcSESE;"); - output.println(" psem_take( &(common->stallSem) );"); + + output.println(" SESEcommon* childCom = (SESEcommon*) "+dynVar+"_srcSESE;"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + output.println(" pthread_mutex_lock( &(childCom->lock) );"); + output.println(" if( childCom->doneExecuting == FALSE ) {"); + output.println(" psem_reset( &runningSESEstallSem );"); + output.println(" childCom->parentsStallSem = &runningSESEstallSem;"); + output.println(" pthread_mutex_unlock( &(childCom->lock) );"); + output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );"); + output.println(" } else {"); + output.println(" pthread_mutex_unlock( &(childCom->lock) );"); + output.println(" }"); FlatMethod fmContext; if( currentSESE.getIsCallerSESEplaceholder() ) { @@ -2827,20 +3183,26 @@ public class BuildCode { fmContext = currentSESE.getfmBogus(); } - TypeDescriptor type=dynVar.getType(); - String typeStr; - if( type.isNull() ) { - typeStr = "void*"; - } else if( type.isClass() || type.isArray() ) { - typeStr = "struct "+type.getSafeSymbol()+"*"; - } else { - typeStr = type.getSafeSymbol(); - } + TypeDescriptor type = dynVar.getType(); + String typeStr; + if( type.isNull() ) { + typeStr = "void*"; + } else if( type.isClass() || type.isArray() ) { + typeStr = "struct "+type.getSafeSymbol()+"*"; + } else { + typeStr = type.getSafeSymbol(); + } output.println(" "+generateTemp( fmContext, dynVar, null )+ - " = *(("+typeStr+"*) ("+ - dynVar+"_srcSESE + "+dynVar+"_srcOffset));"); - + " = *(("+typeStr+"*) ((void*)"+ + dynVar+"_srcSESE + "+dynVar+"_srcOffset));"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLVAR"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + output.println(" }"); output.println(" }"); } @@ -2852,8 +3214,26 @@ public class BuildCode { Map.Entry me = (Map.Entry) dynAssignItr.next(); TempDescriptor lhs = (TempDescriptor) me.getKey(); TempDescriptor rhs = (TempDescriptor) me.getValue(); + + output.println(" {"); + output.println(" SESEcommon* oldSrc = "+lhs+"_srcSESE;"); + output.println(" "+lhs+"_srcSESE = "+rhs+"_srcSESE;"); output.println(" "+lhs+"_srcOffset = "+rhs+"_srcOffset;"); + + // no matter what we did above, track reference count of whatever + // this variable pointed to, do release last in case we're just + // copying the same value in because 1->2->1 is safe but ref count + // 1->0->1 has a window where it looks like it should be free'd + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" if( "+rhs+"_srcSESE != NULL ) {"); + output.println(" ADD_REFERENCE_TO( "+rhs+"_srcSESE );"); + output.println(" }"); + output.println(" if( oldSrc != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( oldSrc );"); + output.println(" }"); + output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); } // for each lhs that is dynamic from a non-dynamic source, set the @@ -2862,87 +3242,121 @@ public class BuildCode { while( dynItr.hasNext() ) { TempDescriptor dynVar = dynItr.next(); assert currentSESE.getDynamicVarSet().contains( dynVar ); + + // first release a reference to current record + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" if( "+dynVar+"_srcSESE != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( oldSrc );"); + output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + output.println(" "+dynVar+"_srcSESE = NULL;"); } - // eom - // handling stall site - if (state.OOOJAVA) { - Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(currentSESE); - if(graph!=null){ - Set seseLockSet = oooa.getLockMappings(graph); - Set waitingElementSet = - graph.getStallSiteWaitingElementSet(fn, seseLockSet); - - if(waitingElementSet.size()>0){ - output.println("// stall on parent's stall sites "); - output.println(" {"); - output.println(" REntry* rentry;"); - - for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { - Analysis.OoOJava.WaitingElement waitingElement = (Analysis.OoOJava.WaitingElement) iterator.next(); + // eom + // handling stall site + if (state.OOOJAVA) { + Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(currentSESE); + if(graph!=null){ + Set seseLockSet = oooa.getLockMappings(graph); + Set waitingElementSet = graph.getStallSiteWaitingElementSet(fn, seseLockSet); - if( waitingElement.getStatus() >= ConflictNode.COARSE ){ - output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseCaller);"); - }else{ - output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseCaller, (void*)&" +generateTemp(fm,waitingElement.getTempDesc(),lb)+ ");"); - } - output.println(" psem_init( &(rentry->parentStallSem) );"); - output.println(" rentry->queue=seseCaller->memoryQueueArray["+ waitingElement.getQueueID()+ "];"); - output - .println(" if(ADDRENTRY(seseCaller->memoryQueueArray["+ waitingElement.getQueueID() - + "],rentry)==NOTREADY){"); - output.println(" psem_take( &(rentry->parentStallSem) );"); - output.println(" } "); + if(waitingElementSet.size()>0){ + output.println("// stall on parent's stall sites "); + output.println(" {"); + output.println(" REntry* rentry;"); + + for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { + Analysis.OoOJava.WaitingElement waitingElement = (Analysis.OoOJava.WaitingElement) iterator.next(); + if( waitingElement.getStatus() >= ConflictNode.COARSE ){ + output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", runningSESE);"); + }else{ + output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", runningSESE, (void*)&" +generateTemp(fm,waitingElement.getTempDesc(),lb)+ ");"); + } + output.println(" psem_init( &(rentry->parentStallSem) );"); + output.println(" rentry->tag=rentry->parentStallSem.tag;"); + output.println(" rentry->queue=runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "];"); + output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "],rentry)==NOTREADY){"); + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + if(state.RCR) { + //no need to enqueue parent effect if coarse grained conflict clears us + output.println(" while(stallrecord.common.rcrstatus) ;"); + output.println(" BARRIER();"); + output.println(" stallrecord.common.parentsStallSem=&rentry->parentStallSem;"); + output.println(" stallrecord.tag=rentry->tag;"); + output.println(" stallrecord.___obj___=(struct ___Object___ *)"+generateTemp(fm, waitingElement.getTempDesc(), null)+";"); + output.println(" stallrecord.common.classID=-"+rcr.getTraverserID(waitingElement.getTempDesc(), fn)+";"); + //mark the record used..so we won't use it again until it is free + output.println(" stallrecord.common.rcrstatus=1;"); + output.println(" enqueueTR(TRqueue, (void *)&stallrecord);"); + } + output.println(" psem_take( &(rentry->parentStallSem), (struct garbagelist *)&___locals___ );"); + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + output.println(" } "); + } + output.println(" }"); + } } - output.println(" }"); - } - } - }else{ - ParentChildConflictsMap conflictsMap = mlpa.getConflictsResults().get(fn); - if (conflictsMap != null) { - Set allocSet = conflictsMap.getAllocationSiteIDSetofStallSite(); - if (allocSet.size() > 0) { - FlatNode enclosingFlatNode=null; - if( currentSESE.getIsCallerSESEplaceholder() && currentSESE.getParent()==null){ - enclosingFlatNode=currentSESE.getfmEnclosing(); - }else{ - enclosingFlatNode=currentSESE; - } - ConflictGraph graph=mlpa.getConflictGraphResults().get(enclosingFlatNode); - HashSet seseLockSet=mlpa.getConflictGraphLockMap().get(graph); - Set waitingElementSet=graph.getStallSiteWaitingElementSet(conflictsMap, seseLockSet); + }else{ + ParentChildConflictsMap conflictsMap = mlpa.getConflictsResults().get(fn); + if (conflictsMap != null) { + Set allocSet = conflictsMap.getAllocationSiteIDSetofStallSite(); + if (allocSet.size() > 0) { + FlatNode enclosingFlatNode=null; + if( currentSESE.getIsCallerSESEplaceholder() && currentSESE.getParent()==null){ + enclosingFlatNode=currentSESE.getfmEnclosing(); + }else{ + enclosingFlatNode=currentSESE; + } + ConflictGraph graph=mlpa.getConflictGraphResults().get(enclosingFlatNode); + HashSet seseLockSet=mlpa.getConflictGraphLockMap().get(graph); + Set waitingElementSet=graph.getStallSiteWaitingElementSet(conflictsMap, seseLockSet); - if(waitingElementSet.size()>0){ - output.println("// stall on parent's stall sites "); - output.println(" {"); - output.println(" REntry* rentry;"); + if(waitingElementSet.size()>0){ + output.println("// stall on parent's stall sites "); + output.println(" {"); + output.println(" REntry* rentry;"); - for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { - WaitingElement waitingElement = (WaitingElement) iterator.next(); + for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) { + WaitingElement waitingElement = (WaitingElement) iterator.next(); - if( waitingElement.getStatus() >= ConflictNode.COARSE ){ - output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseCaller);"); - }else{ - output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseCaller, (void*)&___locals___."+ waitingElement.getDynID() + ");"); - // output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseCaller, ___locals___."+ waitingElement.getDynID() + "->oid);"); - } - output.println(" psem_init( &(rentry->parentStallSem) );"); - output.println(" rentry->queue=seseCaller->memoryQueueArray["+ waitingElement.getQueueID()+ "];"); - output - .println(" if(ADDRENTRY(seseCaller->memoryQueueArray["+ waitingElement.getQueueID() - + "],rentry)==NOTREADY){"); - output.println(" psem_take( &(rentry->parentStallSem) );"); - output.println(" } "); - } - output.println(" }"); - } - } - } - } - - - } + if( waitingElement.getStatus() >= ConflictNode.COARSE ){ + // HERE! a parent might conflict with a child + output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", runningSESE);"); + } else { + output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", runningSESE, (void*)&___locals___."+ waitingElement.getDynID() + ");"); + } + output.println(" psem_init(&(rentry->parentStallSem));"); + output.println(" rentry->tag=rentry->parentStallSem->tag;"); + output.println(" rentry->queue=runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "];"); + output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+"],rentry)==NOTREADY) {"); + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + output.println(" psem_take( &(rentry->parentStallSem), (struct garbagelist *)&___locals___ );"); + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKSTALLMEM"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + output.println(" } "); + } + output.println(" }"); + } + } + } + } + } } switch(fn.kind()) { @@ -3022,6 +3436,11 @@ public class BuildCode { output.println("/* nop */"); break; + case FKind.FlatGenReachNode: + // this node is just for generating a reach graph + // in disjointness analysis at a particular program point + break; + case FKind.FlatExit: output.println("/* exit */"); break; @@ -3452,8 +3871,7 @@ public class BuildCode { public void generateFlatSESEEnterNode( FlatMethod fm, LocalityBinding lb, FlatSESEEnterNode fsen, - PrintWriter output - ) { + PrintWriter output) { // if MLP flag is off, okay that SESE nodes are in IR graph, // just skip over them and code generates exactly the same if( !(state.MLP || state.OOOJAVA) ) { @@ -3473,66 +3891,96 @@ public class BuildCode { output.println(" {"); - // set up the parent - if( (state.MLP && fsen == mlpa.getMainSESE()) || - (state.OOOJAVA && fsen == oooa.getMainSESE()) - ) { - output.println(" SESEcommon* parentCommon = NULL;"); - } else { - if( fsen.getParent() == null ) { - System.out.println( "in "+fm+", "+fsen+" has null parent" ); - } - assert fsen.getParent() != null; - if( !fsen.getParent().getIsCallerSESEplaceholder() ) { - output.println(" SESEcommon* parentCommon = &("+paramsprefix+"->common);"); - } else { - //output.println(" SESEcommon* parentCommon = (SESEcommon*) peekItem( seseCallStack );"); - output.println(" SESEcommon* parentCommon = seseCaller;"); - } + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKDISPATCH"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); } - + + // before doing anything, lock your own record and increment the running children - if( (state.MLP && fsen != mlpa.getMainSESE()) || - (state.OOOJAVA && fsen != oooa.getMainSESE()) + if( (state.MLP && fsen != mlpa.getMainSESE()) || + (state.OOOJAVA && fsen != oooa.getMainSESE()) ) { - output.println(" atomic_inc(&parentCommon->numRunningChildren);"); + output.println(" atomic_inc(&(runningSESE->numRunningChildren));"); } - // just allocate the space for this record - output.println(" "+fsen.getSESErecordName()+"* seseToIssue = ("+ - fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+ - fsen.getSESErecordName()+" ) );"); - //eomgc need to set next, size -// output.println(" struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(seseToIssue))[1]);"); + // allocate the space for this record + output.println( "#ifndef OOO_DISABLE_TASKMEMPOOL" ); + + output.println( "#ifdef CP_EVENTID_POOLALLOC"); + output.println( " CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_BEGIN );"); + output.println( "#endif"); + if( (state.MLP && fsen != mlpa.getMainSESE()) || + (state.OOOJAVA && fsen != oooa.getMainSESE()) + ) { + output.println(" "+ + fsen.getSESErecordName()+"* seseToIssue = ("+ + fsen.getSESErecordName()+"*) poolalloc( runningSESE->taskRecordMemPool );"); + } else { + output.println(" "+ + fsen.getSESErecordName()+"* seseToIssue = ("+ + fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+ + fsen.getSESErecordName()+" ) );"); + } + output.println( "#ifdef CP_EVENTID_POOLALLOC"); + output.println( " CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_END );"); + output.println( "#endif"); + + output.println( "#else // OOO_DISABLE_TASKMEMPOOL" ); + output.println(" "+ + fsen.getSESErecordName()+"* seseToIssue = ("+ + fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+ + fsen.getSESErecordName()+" ) );"); + output.println( "#endif // OOO_DISABLE_TASKMEMPOOL" ); + + + // set up the SESE in-set and out-set objects, which look + // like a garbage list output.println(" struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(seseToIssue))[1]);"); - // sizeof(int)*2 + sizeof(void*)*calculateSizeOfSESEParamList(fsen) - //output.println(" // sizeof(int)*2+sizeof(void*)*"+calculateSizeOfSESEParamList(fsen)); - //output.println(" // blah="+calculateSizeOfSESEParamSize(fsen)); - output.println(" (seseToIssue->common).offsetsize=sizeof(int)+sizeof(void*)+sizeof(void*)*"+calculateSizeOfSESEParamList(fsen)+calculateSizeOfSESEParamSize(fsen)+";"); output.println(" gl->size="+calculateSizeOfSESEParamList(fsen)+";"); -// output.println(" gl->next = (struct garbagelist *)&___locals___;"); - output.println(" seseToIssue->prevSESECount="+calculatePrevSESECount(fsen)+";"); -// output.println(" seseToIssue->prevSESECount=50;"); output.println(" gl->next = NULL;"); -// output.println(" seseToIssue->size = "+calculateSizeOfSESEParamList(fsen)+";"); -// output.println(" seseToIssue->next = &___locals___;"); + if(state.RCR) { + //flag the SESE status as 1...it will be reset + output.println(" seseToIssue->common.rcrstatus=1;"); + } - // and keep the thread-local sese stack up to date - //output.println(" addNewItem( seseCallStack, (void*) seseToIssue);"); + // there are pointers to SESE records the newly-issued SESE + // will use to get values it depends on them for--how many + // are there, and what is the offset from the total SESE + // record to the first dependent record pointer? + output.println(" seseToIssue->common.numDependentSESErecords="+ + fsen.getNumDepRecs()+";"); + + // we only need this (and it will only compile) when the number of dependent + // SESE records is non-zero + if( fsen.getFirstDepRecField() != null ) { + output.println(" seseToIssue->common.offsetToDepSESErecords=(INTPTR)sizeof("+ + fsen.getSESErecordName()+") - (INTPTR)&((("+ + fsen.getSESErecordName()+"*)0)->"+fsen.getFirstDepRecField()+");" + ); + } + + if (state.RCR&&fsen.getInVarsForDynamicCoarseConflictResolution().size()>0) { + output.println(" seseToIssue->common.offsetToParamRecords=(INTPTR) & ((("+fsen.getSESErecordName()+"*)0)->rcrRecords);"); + } // fill in common data output.println(" int localCount=0;"); output.println(" seseToIssue->common.classID = "+fsen.getIdentifier()+";"); - output.println(" psem_init( &(seseToIssue->common.stallSem) );"); - + output.println(" seseToIssue->common.parentsStallSem = NULL;"); output.println(" seseToIssue->common.forwardList = createQueue();"); output.println(" seseToIssue->common.unresolvedDependencies = 10000;"); - output.println(" pthread_cond_init( &(seseToIssue->common.doneCond), NULL );"); output.println(" seseToIssue->common.doneExecuting = FALSE;"); output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );"); output.println(" seseToIssue->common.numRunningChildren = 0;"); - output.println(" seseToIssue->common.parent = parentCommon;"); + output.println(" seseToIssue->common.parent = runningSESE;"); + // start with refCount = 2, one being the count that the child itself + // will decrement when it retires, to say it is done using its own + // record, and the other count is for the parent that will remember + // the static name of this new child below + output.println(" seseToIssue->common.refCount = 2;"); // all READY in-vars should be copied now and be done with it Iterator tempItr = fsen.getReadyInVarSet().iterator(); @@ -3563,9 +4011,9 @@ public class BuildCode { } // before potentially adding this SESE to other forwarding lists, - // create it's lock and take it immediately + // create it's lock output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );"); -// output.println(" pthread_mutex_lock( &(seseToIssue->common.lock) );"); + if( (state.MLP && fsen != mlpa.getMainSESE()) || (state.OOOJAVA && fsen != oooa.getMainSESE()) @@ -3576,30 +4024,23 @@ public class BuildCode { SESEandAgePair srcPair = staticSrcsItr.next(); output.println(" {"); output.println(" SESEcommon* src = (SESEcommon*)"+srcPair+";"); - //eomgc - if(GENERATEPRECISEGC){ - output.println(" stopforgc((struct garbagelist *)&___locals___);"); - } output.println(" pthread_mutex_lock( &(src->lock) );"); - if(GENERATEPRECISEGC){ - output.println(" restartaftergc();"); - } - output.println(" if( !isEmpty( src->forwardList ) &&"); - output.println(" seseToIssue == peekItem( src->forwardList ) ) {"); - output.println(" printf( \"This shouldnt already be here\\n\");"); - output.println(" exit( -1 );"); - output.println(" }"); + // FORWARD TODO output.println(" if( !src->doneExecuting ) {"); - output.println(" addNewItem( src->forwardList, seseToIssue );"); -// output.println(" ++(seseToIssue->common.unresolvedDependencies);"); + output.println(" addNewItem( src->forwardList, seseToIssue );"); output.println(" ++(localCount);"); output.println(" }"); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" ADD_REFERENCE_TO( src );"); + output.println("#endif" ); output.println(" pthread_mutex_unlock( &(src->lock) );"); output.println(" }"); // whether or not it is an outstanding dependency, make sure // to pass the static name to the child's record - output.println(" seseToIssue->"+srcPair+" = "+srcPair+";"); + output.println(" seseToIssue->"+srcPair+" = "+ + "("+srcPair.getSESE().getSESErecordName()+"*)"+ + srcPair+";"); } // dynamic sources might already be accounted for in the static list, @@ -3614,22 +4055,20 @@ public class BuildCode { // the address off to the new child, because you're not done executing and // might change the variable, so copy it right now output.println(" if( src != NULL ) {"); - //eomgc - if(GENERATEPRECISEGC){ - output.println(" stopforgc((struct garbagelist *)&___locals___);"); - } output.println(" pthread_mutex_lock( &(src->lock) );"); - if(GENERATEPRECISEGC){ - output.println(" restartaftergc();"); - } + + // FORWARD TODO + output.println(" if( isEmpty( src->forwardList ) ||"); output.println(" seseToIssue != peekItem( src->forwardList ) ) {"); output.println(" if( !src->doneExecuting ) {"); output.println(" addNewItem( src->forwardList, seseToIssue );"); -// output.println(" ++(seseToIssue->common.unresolvedDependencies);"); output.println(" ++(localCount);"); output.println(" }"); output.println(" }"); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" ADD_REFERENCE_TO( src );"); + output.println("#endif" ); output.println(" pthread_mutex_unlock( &(src->lock) );"); output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;"); output.println(" } else {"); @@ -3658,28 +4097,54 @@ public class BuildCode { // gets passed so child knows it already has the dynamic value output.println(" seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;"); } + + + // maintain pointers for finding dynamic SESE // instances from static names - SESEandAgePair pair = new SESEandAgePair( fsen, 0 ); + SESEandAgePair pairNewest = new SESEandAgePair( fsen, 0 ); + SESEandAgePair pairOldest = new SESEandAgePair( fsen, fsen.getOldestAgeToTrack() ); if( fsen.getParent() != null && - //!fsen.getParent().getIsCallerSESEplaceholder() && - fsen.getParent().getNeededStaticNames().contains( pair ) + fsen.getParent().getNeededStaticNames().contains( pairNewest ) ) { + output.println(" {"); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" SESEcommon* oldest = "+pairOldest+";"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) { SESEandAgePair pair1 = new SESEandAgePair( fsen, i ); SESEandAgePair pair2 = new SESEandAgePair( fsen, i-1 ); - output.println(" "+pair1+" = "+pair2+";"); + output.println(" "+pair1+" = "+pair2+";"); } - output.println(" "+pair+" = seseToIssue;"); + output.println(" "+pairNewest+" = &(seseToIssue->common);"); + + // no need to add a reference to whatever is the newest record, because + // we initialized seseToIssue->refCount to *2* + // but release a reference to whatever was the oldest BEFORE the shift + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" if( oldest != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( oldest );"); + output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + output.println(" }"); } - + + + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_PREPAREMEMQ"); + output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } + + //////////////// // count up memory conflict dependencies, - // eom - if(state.OOOJAVA){ - + if(state.RCR) { + dispatchMEMRC(fm, lb, fsen, output); + } else if(state.OOOJAVA){ FlatSESEEnterNode parent = fsen.getParent(); Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent); if (graph != null && graph.hasConflictEdge()) { @@ -3688,269 +4153,298 @@ public class BuildCode { output.println(" //add memory queue element"); Analysis.OoOJava.SESEWaitingQueue seseWaitingQueue= graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet); - if(seseWaitingQueue.getWaitingElementSize()>0){ + if(seseWaitingQueue.getWaitingElementSize()>0) { output.println(" {"); output.println(" REntry* rentry=NULL;"); output.println(" INTPTR* pointer=NULL;"); output.println(" seseToIssue->common.rentryIdx=0;"); - + Set queueIDSet=seseWaitingQueue.getQueueIDSet(); - for (Iterator iterator = queueIDSet.iterator(); iterator - .hasNext();) { + for (Iterator iterator = queueIDSet.iterator(); iterator.hasNext();) { Integer key = (Integer) iterator.next(); int queueID=key.intValue(); Set waitingQueueSet = seseWaitingQueue.getWaitingElementSet(queueID); int enqueueType=seseWaitingQueue.getType(queueID); - if(enqueueType==SESEWaitingQueue.EXCEPTION){ - output.println(" INITIALIZEBUF(parentCommon->memoryQueueArray[" - + queueID+ "]);"); + if(enqueueType==SESEWaitingQueue.EXCEPTION) { + output.println(" INITIALIZEBUF(runningSESE->memoryQueueArray[" + queueID+ "]);"); } - for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2 - .hasNext();) { + for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2.hasNext();) { Analysis.OoOJava.WaitingElement waitingElement = (Analysis.OoOJava.WaitingElement) iterator2.next(); if (waitingElement.getStatus() >= ConflictNode.COARSE) { output.println(" rentry=mlpCreateREntry(" - + waitingElement.getStatus() - + ", seseToIssue);"); + + waitingElement.getStatus() + + ", &(seseToIssue->common));"); } else { - TempDescriptor td = waitingElement - .getTempDesc(); + TempDescriptor td = waitingElement.getTempDesc(); // decide whether waiting element is dynamic or static if (fsen.getDynamicInVarSet().contains(td)) { // dynamic in-var case output.println(" pointer=seseToIssue->" - + waitingElement.getDynID() - + "_srcSESE+seseToIssue->" - + waitingElement.getDynID() - + "_srcOffset;"); + + waitingElement.getDynID() + + "_srcSESE+seseToIssue->" + + waitingElement.getDynID() + + "_srcOffset;"); + output.println(" rentry=mlpCreateFineREntry(" + + waitingElement.getStatus() + + ", &(seseToIssue->common), pointer );"); + } else if (fsen.getStaticInVarSet().contains(td)) { + // static in-var case + VariableSourceToken vst = fsen.getStaticInVarSrc(td); + if (vst != null) { + + String srcId = "SESE_" + vst.getSESE().getPrettyIdentifier() + + vst.getSESE().getIdentifier() + + "_" + vst.getAge(); + output.println(" pointer=(void*)&seseToIssue->" + + srcId + + "->" + + waitingElement + .getDynID() + + ";"); + output.println(" rentry=mlpCreateFineREntry(" + + waitingElement.getStatus() + + ", &(seseToIssue->common), pointer );"); + } + } else { + output.println(" rentry=mlpCreateFineREntry(" + + waitingElement.getStatus() + + ", &(seseToIssue->common), (void*)&seseToIssue->" + + waitingElement.getDynID() + + ");"); + } + } + output.println(" rentry->queue=runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + + "];"); + + if(enqueueType==SESEWaitingQueue.NORMAL){ + output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); + output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + + "],rentry)==NOTREADY) {"); + output.println(" localCount++;"); + output.println(" }"); + } else { + output.println(" ADDRENTRYTOBUF(runningSESE->memoryQueueArray[" + waitingElement.getQueueID() + "],rentry);"); + } + } + if(enqueueType!=SESEWaitingQueue.NORMAL){ + output.println(" localCount+=RESOLVEBUF(runningSESE->memoryQueueArray[" + + queueID+ "],&seseToIssue->common);"); + } + } + output.println(" }"); + } + output.println(); + } + } else { + ConflictGraph graph = null; + FlatSESEEnterNode parent = fsen.getParent(); + if (parent != null) { + if (parent.isCallerSESEplaceholder) { + graph = mlpa.getConflictGraphResults().get(parent.getfmEnclosing()); + } else { + graph = mlpa.getConflictGraphResults().get(parent); + } + } + if (graph != null && graph.hasConflictEdge()) { + HashSet seseLockSet = mlpa.getConflictGraphLockMap() + .get(graph); + output.println(); + output.println(" //add memory queue element"); + SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), + seseLockSet); + if(seseWaitingQueue.getWaitingElementSize()>0){ + output.println(" {"); + output.println(" REntry* rentry=NULL;"); + output.println(" INTPTR* pointer=NULL;"); + output.println(" seseToIssue->common.rentryIdx=0;"); + + Set queueIDSet=seseWaitingQueue.getQueueIDSet(); + for (Iterator iterator = queueIDSet.iterator(); iterator + .hasNext();) { + Integer key = (Integer) iterator.next(); + int queueID=key.intValue(); + Set waitingQueueSet = seseWaitingQueue.getWaitingElementSet(queueID); + int enqueueType=seseWaitingQueue.getType(queueID); + if(enqueueType==SESEWaitingQueue.EXCEPTION){ + output.println(" INITIALIZEBUF(runningSESE->memoryQueueArray[" + + queueID+ "]);"); + } + for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2 + .hasNext();) { + WaitingElement waitingElement = (WaitingElement) iterator2 + .next(); + if (waitingElement.getStatus() >= ConflictNode.COARSE) { + output.println(" rentry=mlpCreateREntry(" + + waitingElement.getStatus() + + ", &(seseToIssue->common));"); + } else { + TempDescriptor td = waitingElement + .getTempDesc(); + // decide whether waiting element is dynamic or + // static + if (fsen.getDynamicInVarSet().contains(td)) { + // dynamic in-var case + output.println(" pointer=seseToIssue->" + + waitingElement.getDynID() + + "_srcSESE+seseToIssue->" + + waitingElement.getDynID() + + "_srcOffset;"); output - .println(" rentry=mlpCreateFineREntry(" - + waitingElement - .getStatus() - + ", seseToIssue, pointer );"); + .println(" rentry=mlpCreateFineREntry(" + + waitingElement + .getStatus() + + ", &(seseToIssue->common), pointer );"); } else if (fsen.getStaticInVarSet() - .contains(td)) { + .contains(td)) { // static in-var case VariableSourceToken vst = fsen - .getStaticInVarSrc(td); + .getStaticInVarSrc(td); if (vst != null) { String srcId = "SESE_" - + vst.getSESE() - .getPrettyIdentifier() - + vst.getSESE().getIdentifier() - + "_" + vst.getAge(); + + vst.getSESE() + .getPrettyIdentifier() + + vst.getSESE().getIdentifier() + + "_" + vst.getAge(); output - .println(" pointer=(void*)&seseToIssue->" - + srcId - + "->" - + waitingElement - .getDynID() - + ";"); + .println(" pointer=(void*)&seseToIssue->" + + srcId + + "->" + + waitingElement + .getDynID() + + ";"); output - .println(" rentry=mlpCreateFineREntry(" - + waitingElement - .getStatus() - + ", seseToIssue, pointer );"); + .println(" rentry=mlpCreateFineREntry(" + + waitingElement + .getStatus() + + ", &(seseToIssue->common), pointer );"); } } else { output - .println(" rentry=mlpCreateFineREntry(" - + waitingElement - .getStatus() - + ", seseToIssue, (void*)&seseToIssue->" - + waitingElement.getDynID() - + ");"); + .println(" rentry=mlpCreateFineREntry(" + + waitingElement + .getStatus() + + ", &(seseToIssue->common), (void*)&seseToIssue->" + + waitingElement.getDynID() + + ");"); } } output - .println(" rentry->queue=parentCommon->memoryQueueArray[" - + waitingElement.getQueueID() - + "];"); - + .println(" rentry->queue=runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + + "];"); + if(enqueueType==SESEWaitingQueue.NORMAL){ output - .println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); + .println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); output - .println(" if(ADDRENTRY(parentCommon->memoryQueueArray[" - + waitingElement.getQueueID() - + "],rentry)==NOTREADY){"); - output.println(" ++(localCount);"); - output.println(" }"); + .println(" if(ADDRENTRY(runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + + "],rentry)==NOTREADY){"); + output.println(" ++(localCount);"); + output.println(" } "); }else{ output - .println(" ADDRENTRYTOBUF(parentCommon->memoryQueueArray[" - + waitingElement.getQueueID() - + "],rentry);"); + .println(" ADDRENTRYTOBUF(runningSESE->memoryQueueArray[" + + waitingElement.getQueueID() + + "],rentry);"); } } if(enqueueType!=SESEWaitingQueue.NORMAL){ - output.println(" localCount+=RESOLVEBUF(parentCommon->memoryQueueArray[" - + queueID+ "],&seseToIssue->common);"); - } + output.println(" localCount+=RESOLVEBUF(runningSESE->memoryQueueArray[" + + queueID+ "],&seseToIssue->common);"); + } } output.println(" }"); } output.println(); } - - }else{ - ConflictGraph graph = null; - FlatSESEEnterNode parent = fsen.getParent(); - if (parent != null) { - if (parent.isCallerSESEplaceholder) { - graph = mlpa.getConflictGraphResults().get(parent.getfmEnclosing()); - } else { - graph = mlpa.getConflictGraphResults().get(parent); - } - } - if (graph != null && graph.hasConflictEdge()) { - HashSet seseLockSet = mlpa.getConflictGraphLockMap() - .get(graph); - output.println(); - output.println(" //add memory queue element"); - SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), - seseLockSet); - if(seseWaitingQueue.getWaitingElementSize()>0){ - output.println(" {"); - output.println(" REntry* rentry=NULL;"); - output.println(" INTPTR* pointer=NULL;"); - output.println(" seseToIssue->common.rentryIdx=0;"); - - Set queueIDSet=seseWaitingQueue.getQueueIDSet(); - for (Iterator iterator = queueIDSet.iterator(); iterator - .hasNext();) { - Integer key = (Integer) iterator.next(); - int queueID=key.intValue(); - Set waitingQueueSet = seseWaitingQueue.getWaitingElementSet(queueID); - int enqueueType=seseWaitingQueue.getType(queueID); - if(enqueueType==SESEWaitingQueue.EXCEPTION){ - output.println(" INITIALIZEBUF(parentCommon->memoryQueueArray[" - + queueID+ "]);"); - } - for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2 - .hasNext();) { - WaitingElement waitingElement = (WaitingElement) iterator2 - .next(); - if (waitingElement.getStatus() >= ConflictNode.COARSE) { - output.println(" rentry=mlpCreateREntry(" - + waitingElement.getStatus() - + ", seseToIssue);"); - } else { - TempDescriptor td = waitingElement - .getTempDesc(); - // decide whether waiting element is dynamic or - // static - if (fsen.getDynamicInVarSet().contains(td)) { - // dynamic in-var case - output.println(" pointer=seseToIssue->" - + waitingElement.getDynID() - + "_srcSESE+seseToIssue->" - + waitingElement.getDynID() - + "_srcOffset;"); - output - .println(" rentry=mlpCreateFineREntry(" - + waitingElement - .getStatus() - + ", seseToIssue, pointer );"); - } else if (fsen.getStaticInVarSet() - .contains(td)) { - // static in-var case - VariableSourceToken vst = fsen - .getStaticInVarSrc(td); - if (vst != null) { - - String srcId = "SESE_" - + vst.getSESE() - .getPrettyIdentifier() - + vst.getSESE().getIdentifier() - + "_" + vst.getAge(); - output - .println(" pointer=(void*)&seseToIssue->" - + srcId - + "->" - + waitingElement - .getDynID() - + ";"); - output - .println(" rentry=mlpCreateFineREntry(" - + waitingElement - .getStatus() - + ", seseToIssue, pointer );"); - - } - } else { - output - .println(" rentry=mlpCreateFineREntry(" - + waitingElement - .getStatus() - + ", seseToIssue, (void*)&seseToIssue->" - + waitingElement.getDynID() - + ");"); - } - } - output - .println(" rentry->queue=parentCommon->memoryQueueArray[" - + waitingElement.getQueueID() - + "];"); - - if(enqueueType==SESEWaitingQueue.NORMAL){ - output - .println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); - output - .println(" if(ADDRENTRY(parentCommon->memoryQueueArray[" - + waitingElement.getQueueID() - + "],rentry)==NOTREADY){"); - output.println(" ++(localCount);"); - output.println(" } "); - }else{ - output - .println(" ADDRENTRYTOBUF(parentCommon->memoryQueueArray[" - + waitingElement.getQueueID() - + "],rentry);"); - } - } - if(enqueueType!=SESEWaitingQueue.NORMAL){ - output.println(" localCount+=RESOLVEBUF(parentCommon->memoryQueueArray[" - + queueID+ "],&seseToIssue->common);"); - } - } - output.println(" }"); - } - output.println(); - } } - //////////////// } - - // release this SESE for siblings to update its dependencies or, - // eventually, for it to mark itself finished - // output.println(" pthread_mutex_unlock( &(seseToIssue->common.lock) );"); - + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_PREPAREMEMQ"); + output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + + // Enqueue Task Record + if (state.RCR) { + output.println(" enqueueTR(TRqueue, (void *)seseToIssue);"); + } + // if there were no outstanding dependencies, issue here output.println(" if( atomic_sub_and_test(10000-localCount,&(seseToIssue->common.unresolvedDependencies) ) ) {"); output.println(" workScheduleSubmit( (void*)seseToIssue );"); output.println(" }"); - /* - output.println(" if( seseToIssue->common.unresolvedDependencies == 0 ) {"); - output.println(" workScheduleSubmit( (void*)seseToIssue );"); - output.println(" }"); - */ - // release this SESE for siblings to update its dependencies or, - // eventually, for it to mark itself finished -// output.println(" pthread_mutex_unlock( &(seseToIssue->common.lock) );"); + + + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKDISPATCH"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_END );"); + output.println("#endif"); + } + output.println(" }"); } - public void generateFlatSESEExitNode( FlatMethod fm, - LocalityBinding lb, - FlatSESEExitNode fsexn, - PrintWriter output - ) { + void dispatchMEMRC(FlatMethod fm, LocalityBinding lb, FlatSESEEnterNode fsen, PrintWriter output) { + FlatSESEEnterNode parent = fsen.getParent(); + Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(parent); + if (graph != null && graph.hasConflictEdge()) { + Set seseLockSet = oooa.getLockMappings(graph); + Analysis.OoOJava.SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet); + if(seseWaitingQueue.getWaitingElementSize()>0) { + output.println(" {"); + output.println(" REntry* rentry=NULL;"); + output.println(" INTPTR* pointer=NULL;"); + output.println(" seseToIssue->common.rentryIdx=0;"); + output.println(" int dispCount;"); + Vector invars=fsen.getInVarsForDynamicCoarseConflictResolution(); + System.out.println(fm.getMethod()+"["+invars+"]"); + for(int i=0;i weset=seseWaitingQueue.getWaitingElementSet(td); + if (weset==null) + System.out.println("ERROR:"+td+" "+fsen+" "+fm.getMethod()); + int numqueues=weset.size(); + output.println(" seseToIssue->rcrRecords["+i+"].flag="+numqueues+";"); + output.println(" dispCount=0;"); + for(Iterator wtit=weset.iterator();wtit.hasNext();) { + Analysis.OoOJava.WaitingElement waitingElement=wtit.next(); + int queueID=waitingElement.getQueueID(); + assert(waitingElement.getStatus()>=ConflictNode.COARSE); + output.println(" rentry=mlpCreateREntry(" + waitingElement.getStatus() + ", &(seseToIssue->common));"); + output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); + output.println(" rentry->queue=runningSESE->memoryQueueArray[" + waitingElement.getQueueID()+"];"); + output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "],rentry)==READY) {"); + output.println(" dispCount++;"); + output.println(" }"); + } + output.println(" if(!dispCount || !atomic_sub_and_test(dispCount,&(seseToIssue->rcrRecords["+i+"].flag)))"); + output.println(" localCount++;"); + if (fsen.getDynamicInVarSet().contains(td)) { + // dynamic in-var case + //output.println(" pointer=seseToIssue->" + waitingElement.getDynID()+ "_srcSESE+seseToIssue->"+ waitingElement.getDynID()+ "_srcOffset;"); + //output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", &(seseToIssue->common), pointer );"); + } + } + output.println(" }"); + } + } + } + + public void generateFlatSESEExitNode( FlatMethod fm, + LocalityBinding lb, + FlatSESEExitNode fsexn, + PrintWriter output) { // if MLP flag is off, okay that SESE nodes are in IR graph, // just skip over them and code generates exactly the same @@ -3972,30 +4466,32 @@ public class BuildCode { if( fsen.getIsCallerSESEplaceholder() ) { return; } + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKEXECUTE"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_END );"); + output.println("#endif"); + } output.println(" /* SESE exiting */"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKRETIRE"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_BEGIN );"); + output.println("#endif"); + } - String com = paramsprefix+"->common"; // this SESE cannot be done until all of its children are done // so grab your own lock with the condition variable for watching // that the number of your running children is greater than zero - if (GENERATEPRECISEGC){ - output.println(" stopforgc((struct garbagelist *)&___locals___);"); - } - output.println(" pthread_mutex_lock( &("+com+".lock) );"); - if (GENERATEPRECISEGC){ - output.println(" restartaftergc();"); - } - output.println(" while( "+com+".numRunningChildren > 0 ) {"); - if (GENERATEPRECISEGC){ -// output.println(" stopforgc((struct garbagelist *)&(((SESEcommon*)(___params___))[1]));"); - output.println(" stopforgc((struct garbagelist *)&___locals___);"); - } - output.println(" pthread_cond_wait( &("+com+".runningChildrenCond), &("+com+".lock) );"); - if (GENERATEPRECISEGC){ - output.println(" restartaftergc();"); - } + output.println(" pthread_mutex_lock( &(runningSESE->lock) );"); + output.println(" if( runningSESE->numRunningChildren > 0 ) {"); + output.println(" stopforgc( (struct garbagelist *)&___locals___ );"); + output.println(" do {"); + output.println(" pthread_cond_wait( &(runningSESE->runningChildrenCond), &(runningSESE->lock) );"); + output.println(" } while( runningSESE->numRunningChildren > 0 );"); + output.println(" restartaftergc();"); output.println(" }"); @@ -4036,14 +4532,25 @@ public class BuildCode { " = "+from+";"); } - // mark yourself done, your SESE data is now read-only - output.println(" "+com+".doneExecuting = TRUE;"); - output.println(" pthread_cond_signal( &("+com+".doneCond) );"); - output.println(" pthread_mutex_unlock( &("+com+".lock) );"); + // mark yourself done, your task data is now read-only + output.println(" runningSESE->doneExecuting = TRUE;"); + + // if parent is stalling on you, let them know you're done + if( (state.MLP && fsexn.getFlatEnter() != mlpa.getMainSESE()) || + (state.OOOJAVA && fsexn.getFlatEnter() != oooa.getMainSESE()) + ) { + output.println(" if( runningSESE->parentsStallSem != NULL ) {"); + output.println(" psem_give( runningSESE->parentsStallSem );"); + output.println(" }"); + } + + output.println(" pthread_mutex_unlock( &(runningSESE->lock) );"); // decrement dependency count for all SESE's on your forwarding list - output.println(" while( !isEmpty( "+com+".forwardList ) ) {"); - output.println(" SESEcommon* consumer = (SESEcommon*) getItem( "+com+".forwardList );"); + + // FORWARD TODO + output.println(" while( !isEmpty( runningSESE->forwardList ) ) {"); + output.println(" SESEcommon* consumer = (SESEcommon*) getItem( runningSESE->forwardList );"); output.println(" if(consumer->rentryIdx>0){"); @@ -4053,63 +4560,117 @@ public class BuildCode { output.println(" resolvePointer(consumer->rentryArray[idx]);"); output.println(" }"); output.println(" }"); - - -// output.println(" pthread_mutex_lock( &(consumer->lock) );"); -// output.println(" --(consumer->unresolvedDependencies);"); -// output.println(" if( consumer->unresolvedDependencies == 0 ) {"); - output.println(" if( atomic_sub_and_test(1, &(consumer->unresolvedDependencies)) ){"); + + output.println(" if( atomic_sub_and_test( 1, &(consumer->unresolvedDependencies) ) ){"); output.println(" workScheduleSubmit( (void*)consumer );"); output.println(" }"); -// output.println(" pthread_mutex_unlock( &(consumer->lock) );"); output.println(" }"); // eom // clean up its lock element from waiting queue, and decrement dependency count for next SESE block - if( (state.MLP && fsen != mlpa.getMainSESE()) || - (state.OOOJAVA && fsen != oooa.getMainSESE()) - ) { - - output.println(); - output.println(" /* check memory dependency*/"); - output.println(" {"); - output.println(" int idx;"); - output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){"); - output.println(" REntry* re=___params___->common.rentryArray[idx];"); - output.println(" RETIRERENTRY(re->queue,re);"); - output.println(" }"); - output.println(" }"); - + if((state.MLP && fsen != mlpa.getMainSESE()) || + (state.OOOJAVA && fsen != oooa.getMainSESE())) { + output.println(); + output.println(" /* check memory dependency*/"); + output.println(" {"); + output.println(" int idx;"); + output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){"); + output.println(" REntry* re=___params___->common.rentryArray[idx];"); + output.println(" RETIRERENTRY(re->queue,re);"); + output.println(" }"); + output.println(" }"); } - // if parent is stalling on you, let them know you're done - if( (state.MLP && fsexn.getFlatEnter() != mlpa.getMainSESE()) || - (state.OOOJAVA && fsexn.getFlatEnter() != oooa.getMainSESE()) - ) { - output.println(" psem_give( &("+paramsprefix+"->common.stallSem) );"); + + if (state.RCR&&fsen.getDynamicInVarSet().size()>0) { + /* Make sure the running SESE is finished */ + output.println(" if (unlikely(runningSESE->rcrstatus!=0)) {"); + output.println(" if(!CAS(&runningSESE->rcrstatus,1,0)) {"); + output.println(" while(runningSESE->rcrstatus) {"); + output.println(" BARRIER();"); + output.println(" sched_yield();"); + output.println(" }"); + output.println(" }"); + output.println(" }"); + output.println("{"); + output.println(" int idx,idx2;"); + if (fsen.getDynamicInVarSet().size()==1) { + output.println(" idx=0; {"); + } else { + output.println(" for(idx=0;idx<"+fsen.getDynamicInVarSet().size()+";idx++){"); + } + output.println(" struct rcrRecord *rec="+paramsprefix+"->rcrRecords[idx];"); + output.println(" while(rec!=NULL) {"); + output.println(" for(idx2=0;idx2index;idx2++) {"); + output.println(" rcr_RETIREHASHTABLE(allHashStructures[0],rec,rec->array[idx2], (BinItem_rcr *) rcr->ptrarray[idx2]);"); + output.println(" }");//exit idx2 for loop + output.println(" rec=rec->next;"); + output.println(" }");//exit rec while loop + output.println(" }");//exit idx for loop + output.println("}"); } + // last of all, decrement your parent's number of running children - output.println(" if( "+paramsprefix+"->common.parent != NULL ) {"); - output.println(" if (atomic_sub_and_test(1, &"+paramsprefix+"->common.parent->numRunningChildren)) {"); - if (GENERATEPRECISEGC){ - output.println(" stopforgc((struct garbagelist *)&___locals___);"); - } - output.println(" pthread_mutex_lock( &("+paramsprefix+"->common.parent->lock) );"); - if (GENERATEPRECISEGC){ - output.println(" restartaftergc();"); - } - output.println(" pthread_cond_signal( &("+paramsprefix+"->common.parent->runningChildrenCond) );"); - output.println(" pthread_mutex_unlock( &("+paramsprefix+"->common.parent->lock) );"); + output.println(" if( runningSESE->parent != NULL ) {"); + output.println(" if( atomic_sub_and_test( 1, &(runningSESE->parent->numRunningChildren) ) ) {"); + output.println(" pthread_mutex_lock ( &(runningSESE->parent->lock) );"); + output.println(" pthread_cond_signal ( &(runningSESE->parent->runningChildrenCond) );"); + output.println(" pthread_mutex_unlock( &(runningSESE->parent->lock) );"); output.println(" }"); output.println(" }"); - // this is a thread-only variable that can be handled when critical sese-to-sese - // data has been taken care of--set sese pointer to remember self over method - // calls to a non-zero, invalid address - output.println(" seseCaller = (SESEcommon*) 0x1;"); + // a task has variables to track static/dynamic instances + // that serve as sources, release the parent's ref of each + // non-null var of these types + output.println(" // releasing static SESEs"); + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + Iterator pItr = fsen.getNeededStaticNames().iterator(); + while( pItr.hasNext() ) { + SESEandAgePair pair = pItr.next(); + output.println(" if( "+pair+" != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( "+pair+" );"); + output.println(" }"); + } + output.println(" // releasing dynamic variable sources"); + Iterator dynSrcItr = fsen.getDynamicVarSet().iterator(); + while( dynSrcItr.hasNext() ) { + TempDescriptor dynSrcVar = dynSrcItr.next(); + output.println(" if( "+dynSrcVar+"_srcSESE != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( "+dynSrcVar+"_srcSESE );"); + output.println(" }"); + } + // destroy this task's mempool if it is not a leaf task + if( !fsen.getIsLeafSESE() ) { + output.println(" pooldestroy( runningSESE->taskRecordMemPool );"); + } + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + + + // if this is not the Main sese (which has no parent) then return + // THIS task's record to the PARENT'S task record pool, and only if + // the reference count is now zero + if( (state.MLP && fsen != mlpa.getMainSESE()) || + (state.OOOJAVA && fsen != oooa.getMainSESE()) + ) { + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" RELEASE_REFERENCE_TO( runningSESE );"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + } else { + // the main task has no parent, just free its record + output.println(" mlpFreeSESErecord( runningSESE );"); + } + // as this thread is wrapping up the task, make sure the thread-local var + // for the currently running task record references an invalid task + output.println(" runningSESE = (SESEcommon*) 0x1;"); + + if( state.COREPROF ) { + output.println("#ifdef CP_EVENTID_TASKRETIRE"); + output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_END );"); + output.println("#endif"); + } } public void generateFlatWriteDynamicVarNode( FlatMethod fm, @@ -4134,26 +4695,35 @@ public class BuildCode { VSTWrapper vstW = (VSTWrapper) me.getValue(); VariableSourceToken vst = vstW.vst; - /* - // only do this if the variable in question should be tracked, - // meaning that it was explicitly added to the dynamic var set - if( !current.getDynamicVarSet().contains( vst.getAddrVar() ) ) { - continue; - } - */ + output.println(" {"); + output.println(" SESEcommon* oldSrc = "+refVar+"_srcSESE;"); if( vst == null ) { // if there is no given source, this variable is ready so // mark src pointer NULL to signify that the var is up-to-date - output.println(" "+refVar+"_srcSESE = NULL;"); - continue; - } - - // otherwise we track where it will come from - SESEandAgePair instance = new SESEandAgePair( vst.getSESE(), vst.getAge() ); - output.println(" "+refVar+"_srcSESE = "+instance+";"); - output.println(" "+refVar+"_srcOffset = (int) &((("+ - vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");"); + output.println(" "+refVar+"_srcSESE = NULL;"); + } else { + // otherwise we track where it will come from + SESEandAgePair instance = new SESEandAgePair( vst.getSESE(), vst.getAge() ); + output.println(" "+refVar+"_srcSESE = "+instance+";"); + output.println(" "+refVar+"_srcOffset = (INTPTR) &((("+ + vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");"); + } + + // no matter what we did above, track reference count of whatever + // this variable pointed to, do release last in case we're just + // copying the same value in because 1->2->1 is safe but ref count + // 1->0->1 has a window where it looks like it should be free'd + output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" ); + output.println(" if( "+refVar+"_srcSESE != NULL ) {"); + output.println(" ADD_REFERENCE_TO( "+refVar+"_srcSESE );"); + output.println(" }"); + output.println(" if( oldSrc != NULL ) {"); + output.println(" RELEASE_REFERENCE_TO( oldSrc );"); + output.println(" }"); + output.println("#endif // OOO_DISABLE_TASKMEMPOOL" ); + + output.println(" }"); } } @@ -4184,15 +4754,46 @@ public class BuildCode { private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) { - if( (state.MLP && !nonSESEpass) || - (state.OOOJAVA && !nonSESEpass) - ) { - output.println(" seseCaller = (SESEcommon*)"+paramsprefix+";"); - } - MethodDescriptor md=fc.getMethod(); ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? locality.getBinding(lb, fc) : md); ClassDescriptor cn=md.getClassDesc(); + + // if the called method is a static block or a static method or a constructor + // need to check if it can be invoked inside some static block + if(state.MGC) { + // TODO add version for normal Java later + if((md.isStatic() || md.isStaticBlock() || md.isConstructor()) && + ((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic()))) { + if(!md.isInvokedByStatic()) { + System.err.println("Error: a method that is invoked inside a static block is not tagged!"); + } + // is a static block or is invoked in some static block + ClassDescriptor cd = fm.getMethod().getClassDesc(); + if(cd == cn) { + // the same class, do nothing + // TODO may want to invoke static field initialization here + } else { + if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { + // need to check if the class' static fields have been initialized and/or + // its static blocks have been executed + output.println("#ifdef MGC_STATIC_INIT_CHECK"); + output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); + if(cn.getNumStaticFields() != 0) { + // TODO add static field initialization here + } + if(cn.getNumStaticBlocks() != 0) { + MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); + output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); + } else { + output.println(" global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); + } + output.println("}"); + output.println("#endif // MGC_STATIC_INIT_CHECK"); + } + } + } + } + output.println("{"); if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { if (lb!=null) { @@ -4289,7 +4890,12 @@ public class BuildCode { if (!GENERATEPRECISEGC && !this.state.MULTICOREGC) { if (fc.getThis()!=null) { - TypeDescriptor ptd=md.getThis().getType(); + TypeDescriptor ptd=null; + if(md.getThis() != null) { + ptd = md.getThis().getType(); + } else { + ptd = fc.getThis().getType(); + } if (needcomma) output.print(","); if (ptd.isClass()&&!ptd.isArray()) @@ -4409,8 +5015,52 @@ public class BuildCode { } else{ // DEBUG if(!ffn.getDst().getType().isPrimitive()){ // DEBUG output.println("within((void*)"+generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+");"); -// DEBUG } - output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); +// DEBUG } + if(state.MGC) { + // TODO add version for normal Java later + if(ffn.getField().isStatic()) { + // static field + if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) { + // is a static block or is invoked in some static block + ClassDescriptor cd = fm.getMethod().getClassDesc(); + ClassDescriptor cn = ffn.getSrc().getType().getClassDesc(); + if(cd == cn) { + // the same class, do nothing + // TODO may want to invoke static field initialization here + } else { + if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { + // need to check if the class' static fields have been initialized and/or + // its static blocks have been executed + output.println("#ifdef MGC_STATIC_INIT_CHECK"); + output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); + if(cn.getNumStaticFields() != 0) { + // TODO add static field initialization here + } + if(cn.getNumStaticBlocks() != 0) { + MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); + output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); + } else { + output.println(" global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); + } + output.println("}"); + output.println("#endif // MGC_STATIC_INIT_CHECK"); + } + } + } + // redirect to the global_defs_p structure + if(ffn.getSrc().getType().isStatic()) { + // reference to the static field with Class name + output.println(generateTemp(fm, ffn.getDst(),lb)+"=global_defs_p->"+ ffn.getSrc().getType().getClassDesc().getSafeSymbol()+ffn.getField().getSafeSymbol()+";"); + } else { + output.println(generateTemp(fm, ffn.getDst(),lb)+"=*"+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); + } + //output.println(generateTemp(fm, ffn.getDst(),lb)+"=global_defs_p->"+ffn.getSrc().getType().getClassDesc().getSafeSymbol()+"->"+ ffn.getField().getSafeSymbol()+";"); + } else { + output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); + } + } else { + output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";"); + } } } @@ -4511,8 +5161,51 @@ public class BuildCode { // DEBUG if(!fsfn.getField().getType().isPrimitive()){ // DEBUG output.println("within((void*)"+generateTemp(fm,fsfn.getSrc(),lb)+");"); -// DEBUG } - output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); +// DEBUG } + if(state.MGC) { + // TODO add version for normal Java later + if(fsfn.getField().isStatic()) { + // static field + if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) { + // is a static block or is invoked in some static block + ClassDescriptor cd = fm.getMethod().getClassDesc(); + ClassDescriptor cn = fsfn.getDst().getType().getClassDesc(); + if(cd == cn) { + // the same class, do nothing + // TODO may want to invoke static field initialization here + } else { + if((cn.getNumStaticFields() != 0) || (cn.getNumStaticBlocks() != 0)) { + // need to check if the class' static fields have been initialized and/or + // its static blocks have been executed + output.println("#ifdef MGC_STATIC_INIT_CHECK"); + output.println("if(global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag == 0) {"); + if(cn.getNumStaticFields() != 0) { + // TODO add static field initialization here + } + if(cn.getNumStaticBlocks() != 0) { + MethodDescriptor t_md = (MethodDescriptor)cn.getMethodTable().get("staticblocks"); + output.println(" "+cn.getSafeSymbol()+t_md.getSafeSymbol()+"_"+t_md.getSafeMethodDescriptor()+"();"); + } else { + output.println(" global_defs_p->" + cn.getSafeSymbol()+"static_block_exe_flag = 1;"); + } + output.println("}"); + output.println("#endif // MGC_STATIC_INIT_CHECK"); + } + } + } + // redirect to the global_defs_p structure + if(fsfn.getDst().getType().isStatic()) { + // reference to the static field with Class name + output.println("global_defs_p->" + fsfn.getDst().getType().getClassDesc().getSafeSymbol() + fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); + } else { + output.println("*"+generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); + } + } else { + output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); + } + } else { + output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";"); + } } } @@ -4712,7 +5405,7 @@ public class BuildCode { output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");"); } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { if(this.state.MLP || state.OOOJAVA){ - output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray_oid("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+", oid);"); + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray_mlp("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+", oid, "+oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+");"); output.println(" oid += numWorkers;"); }else{ output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+localsprefixaddr+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");"); @@ -4725,7 +5418,7 @@ public class BuildCode { output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal("+fn.getType().getClassDesc().getId()+");"); } else if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { if (this.state.MLP || state.OOOJAVA){ - output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new_oid("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+", oid);"); + output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new_mlp("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+", oid, "+oooa.getDisjointAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+");"); output.println(" oid += numWorkers;"); } else { output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+localsprefixaddr+", "+fn.getType().getClassDesc().getId()+");"); @@ -4842,6 +5535,14 @@ public class BuildCode { } protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) { + if(state.MGC) { + // TODO add version for normal Java later + if((fm.getMethod() != null) && (fm.getMethod().isStaticBlock())) { + // a static block, check if it has been executed + output.println(" global_defs_p->" + fm.getMethod().getClassDesc().getSafeSymbol()+"static_block_exe_flag = 1;"); + output.println(""); + } + } if (frn.getReturnTemp()!=null) { if (frn.getReturnTemp().getType().isPtr()) output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";"); @@ -5498,70 +6199,49 @@ public class BuildCode { return tdSet.size(); } -private String calculateSizeOfSESEParamSize(FlatSESEEnterNode fsen){ - HashMap map=new HashMap(); - HashSet processed=new HashSet(); - String rtr=""; + private String calculateSizeOfSESEParamSize(FlatSESEEnterNode fsen){ + HashMap map=new HashMap(); + HashSet processed=new HashSet(); + String rtr=""; - // space for all in and out set primitives - Set inSetAndOutSet = new HashSet(); - inSetAndOutSet.addAll( fsen.getInVarSet() ); - inSetAndOutSet.addAll( fsen.getOutVarSet() ); + // space for all in and out set primitives + Set inSetAndOutSet = new HashSet(); + inSetAndOutSet.addAll( fsen.getInVarSet() ); + inSetAndOutSet.addAll( fsen.getOutVarSet() ); - Set inSetAndOutSetPrims = new HashSet(); - - Iterator itr = inSetAndOutSet.iterator(); - while( itr.hasNext() ) { - TempDescriptor temp = itr.next(); - TypeDescriptor type = temp.getType(); - if( !type.isPtr() ) { - inSetAndOutSetPrims.add( temp ); - } - } + Set inSetAndOutSetPrims = new HashSet(); + + Iterator itr = inSetAndOutSet.iterator(); + while( itr.hasNext() ) { + TempDescriptor temp = itr.next(); + TypeDescriptor type = temp.getType(); + if( !type.isPtr() ) { + inSetAndOutSetPrims.add( temp ); + } + } - Iterator itrPrims = inSetAndOutSetPrims.iterator(); - while( itrPrims.hasNext() ) { - TempDescriptor temp = itrPrims.next(); - TypeDescriptor type = temp.getType(); - if(type.isPrimitive()){ - Integer count=map.get(type.getSymbol()); - if(count==null){ - count=new Integer(1); - map.put(type.getSymbol(), count); - }else{ - map.put(type.getSymbol(), new Integer(count.intValue()+1)); - } - } - } + Iterator itrPrims = inSetAndOutSetPrims.iterator(); + while( itrPrims.hasNext() ) { + TempDescriptor temp = itrPrims.next(); + TypeDescriptor type = temp.getType(); + if(type.isPrimitive()){ + Integer count=map.get(type.getSymbol()); + if(count==null){ + count=new Integer(1); + map.put(type.getSymbol(), count); + }else{ + map.put(type.getSymbol(), new Integer(count.intValue()+1)); + } + } + } - Set keySet=map.keySet(); - for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { - String key = (String) iterator.next(); - rtr+="+sizeof("+key+")*"+map.get(key); - } - return rtr; -} - -private int calculatePrevSESECount(FlatSESEEnterNode fsen){ - int count=0; - - // dynamic stuff - IteratoritrDynInVars = fsen.getDynamicInVarSet().iterator(); - while( itrDynInVars.hasNext() ) { - TempDescriptor dynInVar = itrDynInVars.next(); - count++; - } - - // in-set source tracking - Iterator itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator(); - while( itrStaticInVarSrcs.hasNext() ) { - SESEandAgePair srcPair = itrStaticInVarSrcs.next(); - count++; - } - - return count; -} - + Set keySet=map.keySet(); + for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { + String key = (String) iterator.next(); + rtr+="+sizeof("+key+")*"+map.get(key); + } + return rtr; + } }