From 183f657d42726ae941bc255aafd80446b2a12171 Mon Sep 17 00:00:00 2001 From: jjenista Date: Wed, 11 Aug 2010 00:54:44 +0000 Subject: [PATCH] fix sese garbage collection bug calculating offsets to dependent sese pointers --- Robust/src/IR/Flat/BuildCode.java | 260 +++++++++++----------- Robust/src/IR/Flat/FlatSESEEnterNode.java | 32 ++- Robust/src/Runtime/garbage.c | 65 +++--- Robust/src/Runtime/mlp_runtime.h | 5 +- 4 files changed, 203 insertions(+), 159 deletions(-) diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 35bfc4f0..ee5e3c9d 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -548,7 +548,7 @@ public class BuildCode { outmethod.println("#include \"psemaphore.h\""); } if (state.COREPROF) { - outmethod.println("#include \"coreprof\\coreprof.h\""); + outmethod.println("#include \"coreprof.h\""); } //Store the sizes of classes & array elements @@ -1824,8 +1824,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(" void* "+dynSrcVar+"_srcSESE;"); + output.println(" INTPTR "+dynSrcVar+"_srcOffset;"); } } } @@ -1973,6 +1973,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, @@ -2004,91 +2016,97 @@ public class BuildCode { outputStructs.println("};\n"); - // generate the SESE record structure - outputStructs.println(fsen.getSESErecordName()+" {"); - - // data common to any SESE, and it must be placed first so - // a module that doesn't know what kind of SESE record this - // is can cast the pointer to a common struct - outputStructs.println(" SESEcommon common;"); - - // then garbage list stuff - 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 + // 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() ) { + if( type.isPtr() ) { + inSetAndOutSetObjs.add( temp ); + } else { inSetAndOutSetPrims.add( temp ); } } - Iterator itrPrims = inSetAndOutSetPrims.iterator(); - while( itrPrims.hasNext() ) { - TempDescriptor temp = itrPrims.next(); - TypeDescriptor type = temp.getType(); - if(!type.isPrimitive()){ - outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+";"); - } - } + // generate the SESE record structure + outputStructs.println(fsen.getSESErecordName()+" {"); + + // data common to any SESE, and it must be placed first so + // a module that doesn't know what kind of SESE record this + // is can cast the pointer to a common struct + 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;"); + + // 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... 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;"); - } - - itrPrims = inSetAndOutSetPrims.iterator(); + outputStructs.println(" /* next is primitives for in-set and out-set and dynamic tracking */"); + + Iterator 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(" "+temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol()+"; /* in-set or out-set primitive */"); } } - outputStructs.println(" int prevSESECount;"); + // note that the sese record pointer will be added below, just primitive part of tracking here + Iterator itrDynInVars = fsen.getDynamicInVarSet().iterator(); + while( itrDynInVars.hasNext() ) { + TempDescriptor dynInVar = itrDynInVars.next(); + outputStructs.println(" INTPTR "+dynInVar+"_srcOffset; /* dynamic tracking primitive */"); + } + - // 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(" void* "+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( fsen.getFirstDepRecField() != null ) { + outputStructs.println(" /* compiler believes first dependent SESE record field above is: "+ + fsen.getFirstDepRecField()+" */" ); + } + outputStructs.println("};\n"); @@ -2157,8 +2175,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(" void* "+dynSrcVar+"_srcSESE;"); + output.println(" INTPTR "+dynSrcVar+"_srcOffset;"); } // declare local temps for in-set primitives, and if it is @@ -3521,27 +3539,36 @@ public class BuildCode { output.println(" atomic_inc(&parentCommon->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(" "+ + fsen.getSESErecordName()+"* seseToIssue = ("+ + fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+ + fsen.getSESErecordName()+" ) );"); + + // 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___;"); + + // 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()+");" + ); + } - // and keep the thread-local sese stack up to date + // and keep the thread-local sese stack up to date (jjenista--this still relevant??) //output.println(" addNewItem( seseCallStack, (void*) seseToIssue);"); // fill in common data @@ -4183,7 +4210,7 @@ public class BuildCode { // 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) &((("+ + output.println(" "+refVar+"_srcOffset = (INTPTR) &((("+ vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");"); } } @@ -5529,70 +5556,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; + } } diff --git a/Robust/src/IR/Flat/FlatSESEEnterNode.java b/Robust/src/IR/Flat/FlatSESEEnterNode.java index 98569fdd..52985ab5 100644 --- a/Robust/src/IR/Flat/FlatSESEEnterNode.java +++ b/Robust/src/IR/Flat/FlatSESEEnterNode.java @@ -46,7 +46,7 @@ public class FlatSESEEnterNode extends FlatNode { protected Hashtable staticInVar2src; private SESEEffectsSet seseEffectsSet; - + // scope info for this SESE protected FlatMethod fmEnclosing; @@ -57,7 +57,14 @@ public class FlatSESEEnterNode extends FlatNode { // a normal method to code generation protected FlatMethod fmBogus; protected MethodDescriptor mdBogus; - + + // used during code generation to calculate an offset + // into the SESE-specific record, specifically to the + // first field in a sequence of pointers to other SESE + // records which is relevant to garbage collection + protected String firstDepRecField; + protected int numDepRecs; + public FlatSESEEnterNode( SESENode sn ) { this.id = identifier++; @@ -84,6 +91,9 @@ public class FlatSESEEnterNode extends FlatNode { cdEnclosing = null; isCallerSESEplaceholder = false; + + firstDepRecField = null; + numDepRecs = 0; } public void rewriteUse() { @@ -356,5 +366,21 @@ public class FlatSESEEnterNode extends FlatNode { public SESEEffectsSet getSeseEffectsSet(){ return seseEffectsSet; } - + + + public void setFirstDepRecField( String field ) { + firstDepRecField = field; + } + + public String getFirstDepRecField() { + return firstDepRecField; + } + + public void incNumDepRecs() { + ++numDepRecs; + } + + public int getNumDepRecs() { + return numDepRecs; + } } diff --git a/Robust/src/Runtime/garbage.c b/Robust/src/Runtime/garbage.c index 9e7b62ee..33dc8e12 100644 --- a/Robust/src/Runtime/garbage.c +++ b/Robust/src/Runtime/garbage.c @@ -546,10 +546,11 @@ void collect(struct garbagelist * stackptr) { qitem=qitem->next; continue; } - struct garbagelist * gl=(struct garbagelist *)&(((SESEcommon*)(qitem->value))[1]); + SESEcommon* seseRec = (SESEcommon*)(qitem->value); + struct garbagelist * gl=(struct garbagelist *)&(seseRec[1]); struct garbagelist * glroot=gl; // update its ascendant SESEs - updateAscendantSESE(gl); + updateAscendantSESE(seseRec); while(gl!=NULL) { int i; @@ -992,22 +993,22 @@ updateForwardList(struct Queue *forwardList, int prevUpdate){ struct QueueItem * fqItem=getHead(forwardList); while(fqItem!=NULL){ - struct garbagelist * gl=(struct garbagelist *)&(((SESEcommon*)(fqItem->objectptr))[1]); + SESEcommon* seseRec = (SESEcommon*)(fqItem->objectptr); + struct garbagelist * gl=(struct garbagelist *)&(seseRec[1]); if(prevUpdate==TRUE){ - updateAscendantSESE(gl); + updateAscendantSESE(seseRec); } // do something here while(gl!=NULL) { int i; - for(i=0; isize; i++) { - void * orig=gl->array[i]; - ENQUEUE(orig, gl->array[i]); - } - gl=gl->next; + for(i=0; isize; i++) { + void * orig=gl->array[i]; + ENQUEUE(orig, gl->array[i]); + } + gl=gl->next; } - // iterate forwarding list of seseRec - SESEcommon *common=(SESEcommon*)fqItem->objectptr; - struct Queue* fList=common->forwardList; + // iterate forwarding list of seseRec + struct Queue* fList=seseRec->forwardList; updateForwardList(fList,prevUpdate); fqItem=getNextQueueItem(fqItem); } @@ -1031,9 +1032,10 @@ updateMemoryQueue(SESEcommon_p seseParent){ ReadBinItem* readBinItem=(ReadBinItem*)binItem; int ridx; for(ridx=0; ridxindex; ridx++){ - REntry *rentry=readBinItem->array[ridx]; - struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(rentry->seseRec))[1]); - updateAscendantSESE(gl); + REntry *rentry=readBinItem->array[ridx]; + SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec); + struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]); + updateAscendantSESE(seseRec); while(gl!=NULL) { int i; for(i=0; isize; i++) { @@ -1045,8 +1047,9 @@ updateMemoryQueue(SESEcommon_p seseParent){ } }else{ //writebin REntry *rentry=((WriteBinItem*)binItem)->val; - struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(rentry->seseRec))[1]); - updateAscendantSESE(gl); + SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec); + struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]); + updateAscendantSESE(seseRec); while(gl!=NULL) { int i; for(i=0; isize; i++) { @@ -1065,8 +1068,9 @@ updateMemoryQueue(SESEcommon_p seseParent){ for(idx=0; idxindex; idx++){ REntry *rentry=vt->array[idx]; if(rentry!=NULL){ - struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(rentry->seseRec))[1]); - updateAscendantSESE(gl); + SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec); + struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]); + updateAscendantSESE(seseRec); while(gl!=NULL) { int i; for(i=0; isize; i++) { @@ -1081,8 +1085,9 @@ updateMemoryQueue(SESEcommon_p seseParent){ SCC *scc=(SCC*)memoryItem; REntry *rentry=scc->val; if(rentry!=NULL){ - struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(rentry->seseRec))[1]); - updateAscendantSESE(gl); + SESEcommon* seseRec = (SESEcommon*)(rentry->seseRec); + struct garbagelist * gl= (struct garbagelist *)&(seseRec[1]); + updateAscendantSESE(seseRec); while(gl!=NULL) { int i; for(i=0; isize; i++) { @@ -1098,13 +1103,16 @@ updateMemoryQueue(SESEcommon_p seseParent){ } } -updateAscendantSESE(struct garbagelist *gl){ - int offsetsize=*((int*)((void*)gl-sizeof(int))); - int prevSESECount=*((int*)((void*)gl+offsetsize)); - INTPTR tailaddr=(INTPTR)((void*)gl+offsetsize+sizeof(int)); + updateAscendantSESE(SESEcommon* seseRec){ int prevIdx; - for(prevIdx=0; prevIdxnumDependentSESErecords); prevIdx++){ + SESEcommon* prevSESE = (SESEcommon*) + ( + ((INTPTR)seseRec) + + seseRec->offsetToDepSESErecords + + (sizeof(INTPTR)*prevIdx) + ); + if(prevSESE!=NULL){ struct garbagelist * prevgl=(struct garbagelist *)&(((SESEcommon*)(prevSESE))[1]); while(prevgl!=NULL) { @@ -1117,7 +1125,8 @@ updateAscendantSESE(struct garbagelist *gl){ } } } -} + + } #endif int within(void *ptr){ //debug function diff --git a/Robust/src/Runtime/mlp_runtime.h b/Robust/src/Runtime/mlp_runtime.h index 148f8594..a14cf7dc 100644 --- a/Robust/src/Runtime/mlp_runtime.h +++ b/Robust/src/Runtime/mlp_runtime.h @@ -163,7 +163,10 @@ typedef struct SESEcommon_t { struct MemoryQueue_t** memoryQueueArray; struct REntry_t* rentryArray[NUMRENTRY]; struct REntry_t* unresolvedRentryArray[NUMRENTRY]; - int offsetsize; + + int numDependentSESErecords; + int offsetToDepSESErecords; + } SESEcommon; // a thread-local stack of SESEs and function to -- 2.34.1